suppose I want to model a blog
in my first attempt, my v1 of blog looked, nominally, like
pub struct Blog {
pub created_ts: u32,
pub updated_ts: u32,
pub title: String,
pub body: String,
pub author: String,
}
And lets suppose that a bunch of v1 Blogs were inserted into BTreeMap.
Then in my v2 of blog, I wanted to drop the updated_ts and add a contributor.
i.e. my v2 looks like
pub struct Blog {
pub created_ts: u32,
pub title: String,
pub body: String,
pub author: String,
pub contributor: String
}
Then I insert a bunch of v2 blogs. But with this data structure, how do I read the old (v1) version of blogs? And can I read some portions of v2 (such as title) if I have only have v1… are really the key questions.
Assuming a protobuf implementation such as prost (Prost — Rust data encoding library // Lib.rs) , the v1 of Blog could look like:
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Blog {
#[prost(uint32, tag = "1")]
pub created_ts: u32,
#[prost(uint32, tag = "2")]
pub updated_ts: u32,
#[prost(string, tag = "3")]
pub title: ::prost::alloc::string::String,
#[prost(string, tag = "4")]
pub body: ::prost::alloc::string::String,
#[prost(string, tag = "5")]
pub author: ::prost::alloc::string::String,
}
& the v2 could look like
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Blog {
#[prost(uint32, tag = "1")]
pub created_ts: u32,
#[prost(string, tag = "3")]
pub title: ::prost::alloc::string::String,
#[prost(string, tag = "4")]
pub body: ::prost::alloc::string::String,
#[prost(string, tag = "5")]
pub author: ::prost::alloc::string::String,
#[prost(string, tag = "6")]
pub contributor: ::prost::alloc::string::String,
}
Through the use of encode/decode on Blog, you would be able convince yourself that the serialization/deserialization does work as claimed. In the following snippet, I used the v1 version of Blob to persist to file. This version is reading from file the v1 but reading it as v2.
let mut buf :Vec<u8> = Vec::new();
let mut file = File::open("some.bin").unwrap();
let _x = file.read_to_end(&mut buf).unwrap();
let mut new_blog2 = Blog::decode(&*buf).unwrap();
println!("title after decoding --> {}", new_blog2.title);
new_blog2.contributor = "bob@acme.com".to_owned();
The next thing is integrating prost along with stable-structures…stable-structures/examples at main · dfinity/stable-structures · GitHub and look at Custom Types. The main thing is to implement Storable & BoundedStorable for Blog with relevant encode/decode.
hth