more clever version number handling
This commit is contained in:
		
							parent
							
								
									efd3124b29
								
							
						
					
					
						commit
						af1f95c88b
					
				
					 1 changed files with 20 additions and 5 deletions
				
			
		
							
								
								
									
										25
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								src/lib.rs
									
										
									
									
									
								
							|  | @ -47,9 +47,12 @@ pub struct JsonDb<T: Schema> { | ||||||
| /// other fields of the corresponding schema version; earlier versions
 | /// other fields of the corresponding schema version; earlier versions
 | ||||||
| /// will be migrated to the current version automatically.
 | /// will be migrated to the current version automatically.
 | ||||||
| pub trait Schema: DeserializeOwned + Serialize { | pub trait Schema: DeserializeOwned + Serialize { | ||||||
|     const VERSION: u32; |     /// Previous schema that can be migrated into the new schema
 | ||||||
|     type Prev: Schema + Into<Self>; |     type Prev: Schema + Into<Self>; | ||||||
| 
 | 
 | ||||||
|  |     /// Schema version number
 | ||||||
|  |     const VERSION: u32 = Self::Prev::VERSION + 1; | ||||||
|  | 
 | ||||||
|     fn parse(s: &str) -> Result<Self, Error> { |     fn parse(s: &str) -> Result<Self, Error> { | ||||||
|         let Version { version } = serde_json::from_str(s)?; |         let Version { version } = serde_json::from_str(s)?; | ||||||
|         match version.cmp(&Self::VERSION) { |         match version.cmp(&Self::VERSION) { | ||||||
|  | @ -64,11 +67,25 @@ pub trait Schema: DeserializeOwned + Serialize { | ||||||
| ///
 | ///
 | ||||||
| /// Implementing this will automatically implement [`Schema`], with
 | /// Implementing this will automatically implement [`Schema`], with
 | ||||||
| /// version number `0` and `Self` as the previous version.
 | /// version number `0` and `Self` as the previous version.
 | ||||||
| pub trait SchemaV0: DeserializeOwned + Serialize {} | pub trait SchemaV0: DeserializeOwned + Serialize { | ||||||
|  |     /// Set this to false if your version 0 is a pre-`JsonDb` schema
 | ||||||
|  |     /// that does not include a version number.
 | ||||||
|  |     const EXPECT_VERSION_NUMBER: bool = true; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| impl<T: SchemaV0> Schema for T { | impl<T: SchemaV0> Schema for T { | ||||||
|     const VERSION: u32 = 0; |  | ||||||
|     type Prev = Self; |     type Prev = Self; | ||||||
|  |     const VERSION: u32 = 0; | ||||||
|  | 
 | ||||||
|  |     fn parse(s: &str) -> Result<Self, Error> { | ||||||
|  |         if Self::EXPECT_VERSION_NUMBER { | ||||||
|  |             let Version { version } = serde_json::from_str(s)?; | ||||||
|  |             if version != 0 { | ||||||
|  |                 return Err(Error::UnknownVersion(version)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Ok(serde_json::from_str(s)?) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Deserialize)] | #[derive(Deserialize)] | ||||||
|  | @ -216,7 +233,6 @@ mod tests { | ||||||
|         last_updated: i64, |         last_updated: i64, | ||||||
|     } |     } | ||||||
|     impl Schema for V1 { |     impl Schema for V1 { | ||||||
|         const VERSION: u32 = 1; |  | ||||||
|         type Prev = V0; |         type Prev = V0; | ||||||
|     } |     } | ||||||
|     impl From<V0> for V1 { |     impl From<V0> for V1 { | ||||||
|  | @ -248,7 +264,6 @@ mod tests { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     impl Schema for V2 { |     impl Schema for V2 { | ||||||
|         const VERSION: u32 = 2; |  | ||||||
|         type Prev = V1; |         type Prev = V1; | ||||||
|     } |     } | ||||||
|     impl From<V1> for V2 { |     impl From<V1> for V2 { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue