use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
use crate::{
render::markdown::{MarkdownRenderable, RenderError},
roi, RawOrImport,
};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, Hash)]
#[serde(deny_unknown_fields)]
pub struct Problem {
pub languages: Option<BTreeSet<String>>,
pub title: String,
pub description: Option<RawOrImport<MarkdownRenderable, roi::Raw>>,
pub tests: Vec<Test>,
pub points: Option<i32>,
}
impl Problem {
pub(crate) fn as_value(
&self,
world: &impl typst::World,
) -> Result<typst::foundations::Value, RenderError> {
use crate::util;
use typst::foundations::Value;
let mut dict = typst::foundations::Dict::new();
if let Some(langs) = &self.languages {
dict.insert("languages".into(), util::convert(&langs));
}
dict.insert("title".into(), util::convert(&self.title));
if let Some(desc) = &self.description {
dict.insert("description".into(), Value::Content(desc.content(world)?));
}
dict.insert("tests".into(), util::convert(&self.tests));
Ok(Value::Dict(dict))
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
#[serde(deny_unknown_fields)]
pub struct Test {
pub input: String,
pub output: String,
#[serde(default = "crate::default_false")]
pub visible: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default, Hash)]
#[serde(deny_unknown_fields)]
pub struct Packet {
pub title: String,
pub preamble: Option<RawOrImport<MarkdownRenderable, roi::Raw>>,
pub problems: Vec<RawOrImport<Problem>>,
}