serde_cow/
lib.rs

1//! A small library with a [`Cow`] wrappers that implements [`serde::Deserialize`] in the ways that should be expected.
2//!
3//! By default, [`Cow`] is always deserialized to the [`Cow::Owned`] variant due to a lack of specialisation, but this library
4//! provides [`CowStr`] and [`CowBytes`] which deserialize to [`Cow::Borrowed`] if possible, borrowing from the original data.
5//!
6//! # Example
7//!
8//! ```
9//! use std::borrow::Cow;
10//!
11//! use serde_cow::CowStr;
12//!
13//! let source = r#""Hello World""#;
14//!
15//! let normal: Cow<str> = serde_json::from_str(source).unwrap();
16//! assert!(matches!(normal, Cow::Owned(_))); // Wasteful!
17//!
18//! let efficent: CowStr = serde_json::from_str(source).unwrap();
19//! assert!(matches!(efficent.0, Cow::Borrowed(_))); // Zero copy!
20//! ```
21//!
22//! ## Minimum Supported Rust Version
23//!
24//! This is currently 1.56 and is considered a breaking change to increase.
25
26#![no_std]
27#![forbid(unsafe_code)]
28#![warn(clippy::pedantic)]
29
30use alloc::borrow::Cow;
31
32use serde::Deserializer;
33
34mod bytes;
35mod str;
36
37extern crate alloc;
38
39/// A wrapper around [`Cow<str>`] to implement [`serde::Deserialize`] in the expected way.
40pub struct CowStr<'de>(pub Cow<'de, str>);
41
42impl serde::Serialize for CowStr<'_> {
43    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
44        serializer.serialize_str(&self.0)
45    }
46}
47
48impl<'de> serde::Deserialize<'de> for CowStr<'de> {
49    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
50        deserializer.deserialize_string(str::CowStrVisitor)
51    }
52}
53
54/// A wrapper around `Cow<[u8]>` to implement [`serde::Deserialize`] in the expected way.
55pub struct CowBytes<'de>(pub Cow<'de, [u8]>);
56
57impl serde::Serialize for CowBytes<'_> {
58    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
59        serializer.serialize_bytes(&self.0)
60    }
61}
62
63impl<'de> serde::Deserialize<'de> for CowBytes<'de> {
64    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
65        deserializer.deserialize_bytes(bytes::CowBytesVisitor)
66    }
67}