use serde::Serialize;
use typst::foundations::{Dict, Value};
use crate::error::{PublishError, Result};
#[derive(Debug, Default, Clone)]
pub struct DataSet {
pub(crate) inputs: Option<Dict>,
pub(crate) files: Vec<(String, Vec<u8>)>,
}
impl DataSet {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn from_inputs<T: Serialize>(data: T) -> Result<Self> {
Self::new().inputs(data)
}
#[must_use]
pub fn from_dict(dict: Dict) -> Self {
Self {
inputs: Some(dict),
files: Vec::new(),
}
}
pub fn from_json_file<T: Serialize>(name: impl Into<String>, data: T) -> Result<Self> {
Self::new().json_file(name, data)
}
pub fn inputs<T: Serialize>(mut self, data: T) -> Result<Self> {
let value = serde_json::to_value(data)?;
self.inputs = Some(json_to_dict(value));
Ok(self)
}
#[must_use]
pub fn inputs_dict(mut self, dict: Dict) -> Self {
self.inputs = Some(dict);
self
}
pub fn json_file<T: Serialize>(self, name: impl Into<String>, data: T) -> Result<Self> {
let bytes = serde_json::to_vec(&data)?;
self.file(name, bytes)
}
pub fn file(mut self, name: impl Into<String>, bytes: impl Into<Vec<u8>>) -> Result<Self> {
let name = name.into();
if self.files.iter().any(|(existing, _)| existing == &name) {
return Err(PublishError::InvalidTemplate(format!(
"duplicate virtual file '{name}'"
)));
}
self.files.push((name, bytes.into()));
Ok(self)
}
}
fn json_to_dict(value: serde_json::Value) -> Dict {
match serde_json::from_value::<Value>(value) {
Ok(Value::Dict(dict)) => dict,
_ => Dict::new(),
}
}