diff --git a/Cargo.lock b/Cargo.lock index 2fe6aec..d0ce1c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,6 +194,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "faststr" version = "0.2.23" @@ -202,6 +208,7 @@ dependencies = [ "criterion", "itoa", "redis", + "rkyv", "ryu", "serde", "simdutf8", @@ -227,6 +234,12 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hermit-abi" version = "0.4.0" @@ -243,6 +256,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "is-terminal" version = "0.4.13" @@ -296,6 +319,26 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "munge" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -379,6 +422,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "quote" version = "1.0.37" @@ -388,6 +451,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rancor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rayon" version = "1.10.0" @@ -452,6 +524,41 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rend" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc8d57aa48e8477046d7d6296d920a1f50bbbaf45047ec46c52f6d6cccea7ef7" + +[[package]] +name = "rkyv" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a1dfb7c03271e31aad881e521cfe25bda0206ee94b1af152957f4f49e25ee23" +dependencies = [ + "bytes", + "hashbrown", + "indexmap", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa3ca4a30c576aeb76aea84370da286f74d12d32029da8caec3d53b5a36a7539" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ryu" version = "1.0.18" @@ -579,6 +686,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" + [[package]] name = "walkdir" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 45fb102..0c7e311 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,14 +20,17 @@ simdutf8 = { version = "0.1", default-features = false, features = [ redis = { version = "0.26", optional = true, default-features = false } itoa = { version = "1", optional = true } ryu = { version = "1", optional = true } +rkyv = { version = "0.8", optional = true, default-features = false } [features] default = ["std"] -std = ["bytes/std", "simdutf8/std", "serde?/std"] +std = ["bytes/std", "simdutf8/std", "serde?/std", "rkyv?/std"] serde = ["serde/alloc"] serde-unsafe = ["serde"] redis = ["std", "dep:redis", "itoa", "ryu"] redis-unsafe = ["redis"] +rkyv = ["rkyv/alloc"] + [dev-dependencies] static_assertions = { version = "1" } diff --git a/src/lib.rs b/src/lib.rs index 55afbc3..d064c25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -798,3 +798,6 @@ mod redis; #[cfg(feature = "serde")] mod serde; + +#[cfg(feature = "rkyv")] +mod rkyv; diff --git a/src/rkyv.rs b/src/rkyv.rs new file mode 100644 index 0000000..17cfd48 --- /dev/null +++ b/src/rkyv.rs @@ -0,0 +1,48 @@ +#[cfg(not(feature = "std"))] +use alloc::string::String; + +use rancor::{Fallible, Source}; +use rkyv::{ + ser::{Allocator, Writer}, + string::{ArchivedString, StringResolver}, + *, +}; + +use super::FastStr; + +impl Archive for FastStr { + type Archived = ArchivedString; + type Resolver = StringResolver; + + fn resolve(&self, resolver: Self::Resolver, out: Place) { + ArchivedString::resolve_from_str(self, resolver, out); + } +} + +impl Serialize for FastStr +where + S: Fallible + Allocator + Writer + ?Sized, + S::Error: Source, +{ + fn serialize(&self, serializer: &mut S) -> Result { + ArchivedString::serialize_from_str(self, serializer) + } +} + +impl Deserialize for ArchivedString { + fn deserialize(&self, _deserializer: &mut D) -> Result { + Ok(FastStr::new(self.as_str())) + } +} + +impl PartialEq for ArchivedString { + fn eq(&self, other: &FastStr) -> bool { + other.as_str() == self.as_str() + } +} + +impl PartialOrd for ArchivedString { + fn partial_cmp(&self, other: &FastStr) -> Option<::core::cmp::Ordering> { + Some(self.as_str().cmp(other.as_str())) + } +}