cdoc_parser/code_ast/
types.rs1use linked_hash_map::LinkedHashMap;
4use serde::{Deserialize, Serialize};
5
6use cowstr::CowStr;
7use std::io::{BufWriter, Write};
8
9pub trait Output {
10 fn write_string(&self, solution: bool) -> String;
11}
12
13#[derive(Clone, Debug, Serialize, Deserialize)]
16pub enum Content {
17 Markup(CowStr),
18 Src(CowStr),
19}
20
21#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
23pub struct Solution {
24 pub placeholder: Option<CowStr>,
25 pub solution: CowStr,
26}
27
28#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
30#[serde(rename = "value", untagged)]
31pub enum CodeElem {
32 Solution(Solution),
33 Src(String),
34}
35
36#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
37pub enum CodeContent {
38 Plain(CowStr),
39 Parsed {
40 blocks: Vec<CodeElem>,
41 meta: LinkedHashMap<CowStr, CowStr>,
42 hash: u64,
43 },
44}
45
46impl CodeContent {
47 pub fn to_string(&self, with_solution: bool) -> anyhow::Result<String> {
48 let mut buf = BufWriter::new(Vec::new());
49 match &self {
50 CodeContent::Plain(s) => Ok(s.to_string()),
51 CodeContent::Parsed { blocks, .. } => {
52 for block in blocks {
53 match block {
54 CodeElem::Solution(s) => {
55 if with_solution {
56 buf.write_all(s.solution.as_bytes())?;
57 } else {
58 s.placeholder
59 .as_ref()
60 .map(|p| buf.write(p.as_bytes()))
61 .transpose()?;
62 }
63 }
64 CodeElem::Src(s) => {
65 buf.write_all(s.as_bytes())?;
66 }
67 }
68 }
69
70 Ok(String::from_utf8(buf.into_inner()?)?)
71 }
72 }
73 }
74}