1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
use serde_derive::{Deserialize, Serialize}; use serde_json; use std::fs::File; use std::io::Read; use std::io::Write; use std::path::Path; use super::Error; pub type Url = String; pub type Uuid = String; pub type Base64 = String; pub type Hash = String; #[derive(Debug, Serialize, Deserialize)] pub struct RecipePhoto { pub data: Base64, pub filename: String, pub name: String, pub hash: Hash, } #[derive(Debug, Serialize, Deserialize)] pub struct Recipe { pub created: String, pub difficulty: String, pub photo_large: Option<Base64>, pub uid: Uuid, pub photo: Option<String>, pub categories: Vec<String>, pub notes: String, pub prep_time: String, pub cook_time: String, pub source: String, pub source_url: String, pub photo_data: Option<Base64>, pub total_time: String, pub name: String, pub ingredients: String, pub photos: Vec<RecipePhoto>, pub rating: u8, pub description: String, pub photo_hash: Option<Hash>, pub image_url: Option<Url>, pub nutritional_info: String, pub directions: String, #[serde(skip_serializing)] pub hash: Hash, pub servings: String, } impl Recipe { pub fn from_reader<R: Read>(rdr: R) -> Result<Recipe, Error> { let gzip_decoder = libflate::gzip::Decoder::new(rdr)?; Ok(serde_json::from_reader(gzip_decoder)?) } pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Recipe, Error> { Ok(Self::from_reader(File::open(path)?)?) } pub fn to_writer<W: Write>(&self, writer: W) -> Result<(), Error> { let mut gzip_encoder = libflate::gzip::Encoder::new(writer)?; serde_json::to_writer(&mut gzip_encoder, self)?; gzip_encoder.finish().into_result()?; Ok(()) } } #[cfg(test)] mod tests { use super::*; #[test] fn deserialization() { let data = include_bytes!("test/Brownies.paprikarecipe.json"); let result: Result<Recipe, _> = serde_json::from_slice(data); assert!(result.is_ok(), true); let recipe = result.unwrap(); assert_eq!(recipe.name, "Brownies"); } #[test] fn from_file() { let data = include_bytes!("test/Brownies.paprikarecipe"); let result = Recipe::from_reader(&data[..]); let recipe = result.unwrap(); assert_eq!(recipe.name, "Brownies"); } }