diff --git a/Cargo.toml b/Cargo.toml index 22d444456..bd39f64fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ log = "0.4" sdset = "0.3" serde = "1.0" serde_derive = "1.0" +serde_json = { version = "1.0", features = ["preserve_order"] } unidecode = "0.3" [dependencies.toml] diff --git a/src/database/schema.rs b/src/database/schema.rs index 0363f47a3..5b4b48731 100644 --- a/src/database/schema.rs +++ b/src/database/schema.rs @@ -113,6 +113,23 @@ impl Schema { Ok(()) } + pub fn from_json(mut reader: R) -> Result> { + let mut buffer = Vec::new(); + reader.read_to_end(&mut buffer)?; + let builder: SchemaBuilder = serde_json::from_slice(&buffer)?; + Ok(builder.build()) + } + + pub fn to_json(&self, mut writer: W) -> Result<(), Box> { + let identifier = self.inner.identifier.clone(); + let attributes = self.attributes_ordered(); + let builder = SchemaBuilder { identifier, attributes }; + let string = serde_json::to_string_pretty(&builder)?; + writer.write_all(string.as_bytes())?; + + Ok(()) + } + pub(crate) fn read_from_bin(reader: R) -> bincode::Result { let builder: SchemaBuilder = bincode::deserialize_from(reader)?; Ok(builder.build()) @@ -254,4 +271,40 @@ mod tests { Ok(()) } + + #[test] + fn serialize_deserialize_json() -> Result<(), Box> { + let mut builder = SchemaBuilder::with_identifier("id"); + builder.new_attribute("alpha", STORED); + builder.new_attribute("beta", STORED | INDEXED); + builder.new_attribute("gamma", INDEXED); + let schema = builder.build(); + + let mut buffer = Vec::new(); + schema.to_json(&mut buffer)?; + + let schema2 = Schema::from_json(buffer.as_slice())?; + assert_eq!(schema, schema2); + + let data = r#" + { + "identifier": "id", + "attributes": { + "alpha": { + "stored": true + }, + "beta": { + "stored": true, + "indexed": true + }, + "gamma": { + "indexed": true + } + } + }"#; + let schema2 = Schema::from_json(data.as_bytes())?; + assert_eq!(schema, schema2); + + Ok(()) + } }