Skip to main content

rspack_cacheable/with/
as_string.rs

1use rkyv::{
2  Place,
3  rancor::Fallible,
4  ser::Writer,
5  string::{ArchivedString, StringResolver},
6  with::{ArchiveWith, DeserializeWith, SerializeWith},
7};
8
9use crate::{Error, Result};
10
11pub struct AsString;
12
13pub trait AsStringConverter {
14  fn to_string(&self) -> Result<String>;
15  fn from_str(s: &str) -> Result<Self>
16  where
17    Self: Sized;
18}
19
20pub struct AsStringResolver {
21  inner: StringResolver,
22  value: String,
23}
24
25impl<T> ArchiveWith<T> for AsString
26where
27  T: AsStringConverter,
28{
29  type Archived = ArchivedString;
30  type Resolver = AsStringResolver;
31
32  #[inline]
33  fn resolve_with(_field: &T, resolver: Self::Resolver, out: Place<Self::Archived>) {
34    let AsStringResolver { inner, value } = resolver;
35    ArchivedString::resolve_from_str(&value, inner, out);
36  }
37}
38
39impl<T, S> SerializeWith<T, S> for AsString
40where
41  T: AsStringConverter,
42  S: Fallible<Error = Error> + Writer + ?Sized,
43{
44  #[inline]
45  fn serialize_with(field: &T, serializer: &mut S) -> Result<Self::Resolver> {
46    let value = field.to_string()?;
47    let inner = ArchivedString::serialize_from_str(&value, serializer)?;
48    Ok(AsStringResolver { value, inner })
49  }
50}
51
52impl<T, D> DeserializeWith<ArchivedString, T, D> for AsString
53where
54  T: AsStringConverter,
55  D: Fallible<Error = Error> + ?Sized,
56{
57  #[inline]
58  fn deserialize_with(field: &ArchivedString, _: &mut D) -> Result<T> {
59    AsStringConverter::from_str(field.as_str())
60  }
61}