dofus_framework/io/file/
deserializer.rs1use std::fs;
2
3use serde::Deserialize;
4use thiserror::Error;
5
6use crate::io::file::deserializer::DeserializationError::{EmptyFile, IOError, InvalidInput};
7
8#[derive(Debug, Error)]
9pub enum DeserializationError {
10 #[error("Format {0} yet to be implemented")]
11 NotImplemented(String),
12 #[error("Cannot deserialize data:\n\n{0}\n\nas {1} format")]
13 InvalidInput(String, &'static str),
14 #[error("File {0} is empty")]
15 EmptyFile(String),
16 #[error("Error while trying to read the contents of the file")]
17 IOError {
18 path: String,
19 source: std::io::Error,
20 },
21}
22
23pub trait Deserializer {
24 fn deserialize<E>(&self, data: &str) -> Result<E, DeserializationError>
25 where
26 E: for<'a> Deserialize<'a>;
27}
28
29#[derive(Debug)]
30pub enum Format {
31 Json,
32 Yaml,
33 Xml,
34 Toml,
35}
36
37impl Deserializer for Format {
38 fn deserialize<E>(&self, data: &str) -> Result<E, DeserializationError>
39 where
40 E: for<'a> Deserialize<'a>,
41 {
42 match self {
43 Format::Json => deserialize_with_context(|x| serde_json::from_str(x), data, "JSON"),
44 Format::Yaml => deserialize_with_context(serde_yaml::from_str, data, "YAML"),
45 Format::Xml => deserialize_with_context(serde_xml_rs::from_str, data, "XML"),
46 Format::Toml => deserialize_with_context(|x| toml::from_str(x), data, "TOML"),
47 }
49 }
50}
51
52fn deserialize_with_context<T, E>(
53 result: fn(&str) -> Result<T, E>,
54 data: &str,
55 format: &'static str,
56) -> Result<T, DeserializationError> {
57 result(data).map_err(|_| InvalidInput(data.to_string(), format))
58}
59
60pub fn deserialize_from_file<E, T>(
61 file_path: &str,
62 deserializer: T,
63) -> Result<E, DeserializationError>
64where
65 E: for<'a> Deserialize<'a>,
66 T: Deserializer,
67{
68 fs::read_to_string(file_path)
69 .map_err(|err| IOError {
70 path: file_path.to_string(),
71 source: err,
72 })
73 .map(|file_data| {
74 if file_data.is_empty() {
75 return Err(EmptyFile(file_path.to_string()));
76 }
77 deserializer.deserialize(file_data.as_str())
78 })?
79}