chiark / gitweb /
sort out deserialize for ZCoord
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 14 Oct 2020 00:00:50 +0000 (01:00 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 14 Oct 2020 00:00:50 +0000 (01:00 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
zcoord/zcoord.rs

index 39ad3599ca86047a2f21765b06900f3e4c667b3c..bec465cefab534765992a662f3e3a976b9a5fd29 100644 (file)
@@ -71,7 +71,7 @@ use std::fmt::{self, Debug, Display, Formatter};
 use std::num::{TryFromIntError, Wrapping};
 use std::str;
 use fehler::{throw, throws};
-use serde::{Serialize, Serializer, Deserialize};
+use serde::{Serialize, Serializer, Deserialize, Deserializer};
 use thiserror::Error;
 
 //---------- core definitions ----------
@@ -96,8 +96,6 @@ const TEXT_PER_LIMB : usize = DIGITS_PER_LIMB + 1;
 const LIMB_MODULUS : LimbVal = Wrapping(RAW_LIMB_MODULUS);
 const LIMB_MASK    : LimbVal = Wrapping(RAW_LIMB_MODULUS-1);
 
-#[derive(Deserialize)]
-#[serde(try_from="&str")]
 pub struct ZCoord(innards::Innards);
 
 #[derive(Error,Clone,Copy,Debug,Eq,PartialEq,Serialize,Deserialize)]
@@ -450,6 +448,25 @@ impl Serialize for ZCoord {
   }
 }
 
+impl<'de> Deserialize<'de> for ZCoord {
+  fn deserialize<D:Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
+    use serde::de::{Visitor, Error, Unexpected};
+    struct V;
+    impl<'de> Visitor<'de> for V {
+      type Value = ZCoord;
+      fn expecting(&self, f: &mut Formatter) -> fmt::Result {
+        write!(f, "a z coordinate (as a string)")
+      }
+      fn visit_str<E:Error>(self, s: &str) -> Result<Self::Value, E> {
+        ZCoord::from_str(s).map_err(|ParseError| Error::invalid_value(
+          Unexpected::Str(s), &self
+        ))
+      }
+    }
+    d.deserialize_str(V)
+  }
+}
+
 //---------- construction of ZCoord contents ---------
 //
 // We can panic if this code is buggy, but not compromise safety.