use std::fs;
use std::path::{Path, PathBuf};
use serde::Deserialize;
use crate::evaluator::Imports;
#[derive(Debug, Clone, Deserialize)]
pub struct Module<T> {
#[serde(default)]
pub imports: Imports<PathBuf>,
#[serde(flatten)]
pub body: T,
}
pub trait Format<T> {
type Error: std::error::Error + 'static;
fn read(&mut self, path: &Path) -> Result<Module<T>, Self::Error>;
}
#[cfg(feature = "json")]
mod json {
use super::*;
use std::io;
#[derive(Debug, Default, Clone, Copy)]
pub struct Json;
impl<T> Format<T> for Json
where
T: for<'de> Deserialize<'de>,
{
type Error = io::Error;
fn read(&mut self, path: &Path) -> Result<Module<T>, Self::Error> {
let mut reader = fs::File::open(path).map(io::BufReader::new)?;
serde_json::from_reader(&mut reader).map_err(Into::into)
}
}
}
#[cfg(feature = "json")]
pub use self::json::Json;
#[cfg(feature = "toml")]
mod toml {
use super::*;
use ::toml::de::Error;
use serde::de::Error as _;
#[derive(Debug, Default, Clone, Copy)]
pub struct Toml;
impl<T> Format<T> for Toml
where
T: for<'de> Deserialize<'de>,
{
type Error = Error;
fn read(&mut self, path: &Path) -> Result<Module<T>, Self::Error> {
let bytes = fs::read(path).map_err(Error::custom)?;
::toml::from_slice(&bytes)
}
}
}
#[cfg(feature = "toml")]
pub use self::toml::Toml;