Expand description
serde_context provides convenient contextful (de)serialization compatible with the serde ecosystem.
§Basic usage
Any type that implements Context (blanket implementations are provided) can be passed to serialize_with_context
or deserialize_with_context and then accessed by using context_scope within
Serialize and
Deserialize implementations. See these items
respective documentations for more information.
§Features
This crate provides no conditional compilation features. It requires the standard library
because it uses thread_locals to store and access context.
§Limitations
There are a few limitations to this crate:
- Only immutable references may be passed as context. You may still use interior mutability (
Cells,RefCells,UnsafeCells…) to mutate state. - Only types implementing
'staticcan be used as context for (de)serialization. Unsized types are supported, though. - There is no type-checking of required context. Trying to (de)serialize a type that requires some context but failing to provide it will result in a runtime error.
§Alternatives
There are a few alternatives to this crate you might want to consider, each with their pros and cons:
DeserializeSeed: the official serde stateful deserialization-only API. Requires implementing that trait for each type you are interested in deserializing, and no derive macro is provided (nor are there any plans to ever make an official one).serde_state: a fork of serde that supports stateful (de)serialization. Unfortunately, it looks to be unmaintained.serde_seeded: a crate providing an alternative version of theDeserializeSeedtrait with a derive macro for it. Relatively young but very promising.
§Example
This minimal, contrived example showcases the basics of this crate: passing context
to a serialization process and accessing it within a Serialize
implementation. You can find more serious examples in this crate’s
examples directory.
More concretely here, we are inserting a multiplier (MyMultiplier) inside of
this serialization’s global context, and then using it to multiply every numbers
(MyNumber) by it before serialization.
struct MyMultiplier(i32);
struct MyNumber(i32);
impl Serialize for MyNumber {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
context_scope(|cx| {
let mul = cx.get::<MyMultiplier>().map_err(S::Error::custom)?;
(self.0 * mul.0).serialize(serializer)
})
}
}
let mut bytes = Vec::<u8>::new();
let mut serializer = serde_json::Serializer::new(&mut bytes);
serialize_with_context(&MyNumber(6), &mut serializer, &MyMultiplier(7))?;
assert_eq!(bytes, b"42");Structs§
- Context
Ref - Reference to the global context used to retrieve data within it.
- Missing
Context Error - Error that may be returned when requested context is missing.
Traits§
- Context
- Types that can be passed as context for (de)serialization.
Functions§
- context_
scope - Access context provided to
serialize_with_contextordeserialize_with_context. - deserialize_
with_ context - Deserialize a value with some provided context.
- serialize_
with_ context - Serialize a value with some provided context.