J'ai un peu galéré à trouver comment ça marche, parce qu'en fait la doc est pas très bien foutue :
Je voulais rendre déserializable un “newType” autour de Arc<Mutex<T>>
, et j'ai eu du mal à trouver comment je devais faire, donc je copie-colle le code ici, pour mémoire.
pub struct HashMapDirectory(Arc<Mutex<HashMap<PathBuf, HashMapFile>>>);
// La sérialization est assez simple et intuitive
impl Serialize for HashMapDirectory {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_newtype_struct("HashMapDirectory", &*self.0.lock().unwrap())
}
}
// La déserialization par contre, c'est plus chelou, avec un `Visitor` à implémenter, qui fait quelque chose que je n'ai pas bien compris.
struct HashMapDirectoryVisitor {
marker: PhantomData<fn() -> HashMapDirectory>
}
impl HashMapDirectoryVisitor {
fn new() -> Self {
HashMapDirectoryVisitor {
marker: PhantomData
}
}
}
impl<'de> Visitor<'de> for HashMapDirectoryVisitor
{
// The type that our Visitor is going to produce.
type Value = HashMapDirectory;
// Format a message stating what data this Visitor expects to receive.
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a very special map")
}
fn visit_newtype_struct<D>(
self,
deserializer: D
) -> Result<Self::Value, D::Error> where
D: Deserializer<'de> {
Ok(HashMapDirectory(Arc::new(Mutex::new(Deserialize::deserialize(deserializer)?))))
}
}
impl<'de> Deserialize<'de> for HashMapDirectory
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Instantiate our Visitor and ask the Deserializer to drive
// it over the input data, resulting in an instance of MyMap.
deserializer.deserialize_newtype_struct("HashMapDirectory", HashMapDirectoryVisitor::new())
}
}