1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::collections::BTreeMap;

use isolang::Language;
use said::sad::{SerializationFormats, SAD};
use serde::{Deserialize, Serialize};

#[derive(Debug, SAD, Serialize, Deserialize)]
pub struct Presentation {
    #[serde(rename = "bd")]
    pub bundle_digest: said::SelfAddressingIdentifier,
    #[said]
    #[serde(rename = "d")]
    pub said: Option<said::SelfAddressingIdentifier>,
    #[serde(rename = "p")]
    pub pages: BTreeMap<String, Vec<String>>,
    #[serde(rename = "po")]
    pub pages_order: Vec<String>,
    #[serde(rename = "pl")]
    pub pages_label: BTreeMap<Language, BTreeMap<String, String>>,
    #[serde(rename = "i")]
    pub interaction: Vec<Interaction>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Interaction {
    #[serde(rename = "m")]
    pub interaction_method: InteractionMethod,
    #[serde(rename = "c")]
    pub context: Context,
    #[serde(rename = "a")]
    pub attr_properties: BTreeMap<String, Properties>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Properties {
    #[serde(rename = "t")]
    pub type_: AttrType,
}

#[serde(rename_all = "lowercase")]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum AttrType {
    TextArea,
    Signature,
    File,
}

#[serde(rename_all = "lowercase")]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum Context {
    Capture,
}
#[serde(rename_all = "lowercase")]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum InteractionMethod {
    Web,
    Ai,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_presentation_base() {
        let mut pages = BTreeMap::new();
        pages.insert("pageY".to_string(), vec!["attr_1".to_string()]);
        pages.insert(
            "pageZ".to_string(),
            vec!["attr_3".to_string(), "attr_2".to_string()],
        );

        let mut pages_label = BTreeMap::new();
        let mut pages_label_en = BTreeMap::new();
        pages_label_en.insert("pageY".to_string(), "Page Y".to_string());
        pages_label_en.insert("pageZ".to_string(), "Page Z".to_string());
        pages_label.insert(Language::Eng, pages_label_en);

        let mut presentation_base = Presentation {
            bundle_digest: "EHp19U2U1sdOBmPzMmILM3DUI0PQph9tdN3KtmBrvNV7"
                .parse()
                .unwrap(),
            said: None,
            pages,
            pages_order: vec!["pageY".to_string(), "pageZ".to_string()],
            pages_label,
            interaction: vec![Interaction {
                interaction_method: InteractionMethod::Web,
                context: Context::Capture,
                attr_properties: vec![(
                    "attr_1".to_string(),
                    Properties {
                        type_: AttrType::TextArea,
                    },
                )]
                .into_iter()
                .collect(),
            }]
        };

        presentation_base.compute_digest();

        println!(
            "{}",
            serde_json::to_string_pretty(&presentation_base).unwrap()
        );
        assert_eq!(
            presentation_base.said.unwrap().to_string(),
            "EBDKqlEFqzmW00Q6PzsqXb0rPTXeCqYcHS1kwhg76LiF".to_string()
        );
    }
}