Skip to content

Instantly share code, notes, and snippets.

@vmx
Created October 7, 2019 15:53
Show Gist options
  • Save vmx/4181727b91b8f8e54934917036ce37d3 to your computer and use it in GitHub Desktop.
Save vmx/4181727b91b8f8e54934917036ce37d3 to your computer and use it in GitHub Desktop.
Reviving tagged values in Serde
commit 56080751ae37a4202b0681b36ab066bc838d9537
Author: Volker Mische <[email protected]>
Date: Fri Sep 27 00:28:51 2019 +0200
WIP
diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs
index f1b8b312..646714c0 100644
--- a/serde/src/de/mod.rs
+++ b/serde/src/de/mod.rs
@@ -1615,6 +1615,7 @@ pub trait Visitor<'de>: Sized {
{
let _ = deserializer;
Err(Error::invalid_type(Unexpected::NewtypeStruct, &self))
+ //Deserialize::deserialize(deserializer)
}
/// The input contains a sequence of elements.
@@ -1650,6 +1651,17 @@ pub trait Visitor<'de>: Sized {
Err(Error::invalid_type(Unexpected::Enum, &self))
}
+ /// The input contains a tagged value
+ fn visit_tagged_value<T, D>(self, _tag: T, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ T: ::Tagger,
+ D: Deserializer<'de>,
+ {
+ //Deserialize::deserialize(deserializer)
+ Deserializer::deserialize_any(deserializer)
+ //Err(Error::invalid_type(Unexpected::NewtypeStruct, &self))
+ }
+
// Used when deserializing a flattened Option field. Not public API.
#[doc(hidden)]
fn __private_visit_untagged_option<D>(self, _: D) -> Result<Self::Value, ()>
diff --git a/serde/src/lib.rs b/serde/src/lib.rs
index b52c9501..5779d7fc 100644
--- a/serde/src/lib.rs
+++ b/serde/src/lib.rs
@@ -237,11 +237,14 @@ mod integer128;
pub mod de;
pub mod ser;
+mod tagger;
#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};
+#[doc(inline)]
+pub use tagger::Tagger;
// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs
index 8fb2434f..98bef6de 100644
--- a/serde/src/ser/mod.rs
+++ b/serde/src/ser/mod.rs
@@ -1247,6 +1247,17 @@ pub trait Serializer: Sized {
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error>;
+ /// Serialize a tagged value.
+ ///
+ /// By default, the tag is discarded and the value is serialized as-is.
+ fn serialize_tagged_value<T, V>(self, _tag: T, value: V) -> Result<Self::Ok, Self::Error>
+ where
+ T: ::Tagger,
+ V: Serialize,
+ {
+ value.serialize(self)
+ }
+
/// Collect an iterator as a sequence.
///
/// The default implementation serializes each item yielded by the iterator
diff --git a/serde/src/tagger.rs b/serde/src/tagger.rs
new file mode 100644
index 00000000..f1938f3c
--- /dev/null
+++ b/serde/src/tagger.rs
@@ -0,0 +1,32 @@
+/// Provides the correct tag for a given format.
+pub trait Tagger {
+ /// Returns a `u8` tag if available.
+ fn u8_tag(&self, _format: &'static str) -> Option<u8> { None }
+
+ /// Returns a `u16` tag if available.
+ fn u16_tag(&self, _format: &'static str) -> Option<u16> { None }
+
+ /// Returns a `u32` tag if available.
+ fn u32_tag(&self, _format: &'static str) -> Option<u32> { None }
+
+ /// Returns a `u64` tag if available.
+ fn u64_tag(&self, _format: &'static str) -> Option<u64> { None }
+
+ /// Returns an `i8` tag if available.
+ fn i8_tag(&self, _format: &'static str) -> Option<i8> { None }
+
+ /// Returns an `i16` tag if available.
+ fn i16_tag(&self, _format: &'static str) -> Option<i16> { None }
+
+ /// Returns an `i32` tag if available.
+ fn i32_tag(&self, _format: &'static str) -> Option<i32> { None }
+
+ /// Returns an `i64` tag if available.
+ fn i64_tag(&self, _format: &'static str) -> Option<i64> { None }
+
+ /// Provides a string tag if available.
+ fn string_tag(&self, _format: &'static str) -> Option<&str> { None }
+
+ /// Provides a binary tag if available.
+ fn bytes_tag(&self, _format: &'static str) -> Option<&[u8]> { None }
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment