JSON_serialization_with_serde
Last updated
Last updated
Let's say we want to display our data in JSON format. A popular library that many Rust developers use is the crate.
We can add this to our Cargo.toml file like so:
Note that we want to bring in the derive
feature from serde
. This will allow us to derive
the Serialize
implementation for our structs. We'll also bring in serde_json
so that we can convert our struct to a JSON formatted String
.
Let's take an example using a struct from the Rust-Bitcoin library:
So there are two different field types here, the Amount
type and the ScriptBuf
type. These are essentially just wrappers for other types in the form of tuple structs. Let's include those.
This, of course, won't work. We need to implement the Serialize
trait for both the ScriptBuf
and Amount
. This trait is already implemented by default for most primitive and standard types. However, since these are custom types we'll need to implement the Serialize
trait for each of them.
Implement the Serialize
trait for the Amount
and ScriptBuf
structs.
Let's start with a simple version, leveraging the methods available for the Serializer
trait.
Notice that we use the serialize_u64
and serialize_bytes
methods. The serialize_bytes
method accepts a slice
as an argument so we'll call the .as_slice
method on the Vec
.
This will now work and print the json output we expect:
However, there's another problem. We want to print the Amount
in bitcoin and not satoshis. We want to store it in satoshis for internal purposes but serialize it as a bitcoin amount for display purposes.
We can do something like the following:
The as_btc
method accepts a generic type T
so we'll set up a new trait called SerdeAmount
and implement the ser_btc
method.
Now we can add the derive
attribute to TxOut
for Serialize
and see if this works by calling serde_json::to_string_pretty
on our TxOut
struct instance. Remember to bring serde_json
and serde::Serialize
into scope. You can follow along on .
When implementing the Serialize
trait, we must implement the required method, serialize
. This is the method signature: fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error>
. It accepts a type which implements the Serializer
trait. This type will be passed in by serde_json
when we call the to_string_pretty
method. The Serializer
trait has several methods available that we can use to serialize various types, which can be found in the .
With serde
we can provide custom serialization at the field level. See for various field attributes that we can add. This is useful when we want to serialize Amount
differently based on its context.
The full code is available on .