summaryrefslogtreecommitdiff
path: root/src/description/part.rs
blob: 2f1771f3e054e93dc1ce22cffa4c0c017a82f4e2 (plain)
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
use crate::gloss_list::{Error as GlossListError, GlossList};
use crate::itemized_list::{Error as ItemizedListError, ItemizedList};
use crate::paragraph::{Error as ParagraphError, Paragraph};
use crate::table::{Error as TableError, Informal, Table};
use crate::variable_list::{Error as VariableListError, VariableList};
use crate::xml::element::{FromElements, Tagged};

/// Description part.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Part
{
    /// Paragraph.
    Paragraph(Paragraph),

    /// Variable list.
    VariableList(VariableList),

    /// Program listing.
    ProgramListing(String),

    /// Informal table.
    InformalTable(Informal),

    /// Itemized list.
    ItemizedList(ItemizedList),

    /// Table.
    Table(Table),

    /// Gloss list.
    GlossList(GlossList),
}

impl Part
{
    pub(crate) fn from_tagged_element(tagged_element: &Tagged) -> Result<Self, Error>
    {
        match tagged_element.name() {
            "para" => Paragraph::from_elements(tagged_element.child_elements())
                .map(Part::Paragraph)
                .map_err(Error::InvalidParagraph),
            "variablelist" => {
                VariableList::from_elements(tagged_element.child_elements())
                    .map(Part::VariableList)
                    .map_err(Error::InvalidVariableList)
            }
            "programlisting" => Ok(Part::ProgramListing(
                tagged_element
                    .child_elements()
                    .get_first_text_element()
                    .cloned()
                    .unwrap_or_default(),
            )),
            "informaltable" => Informal::from_elements(tagged_element.child_elements())
                .map(Part::InformalTable)
                .map_err(Error::InvalidInformalTable),
            "itemizedlist" => {
                ItemizedList::from_elements(tagged_element.child_elements())
                    .map(Part::ItemizedList)
                    .map_err(Error::InvalidItemizedList)
            }
            "table" => Table::from_elements(tagged_element.child_elements())
                .map(Part::Table)
                .map_err(Error::InvalidTable),
            "glosslist" => GlossList::from_elements(tagged_element.child_elements())
                .map(Part::GlossList)
                .map_err(Error::InvalidGlossList),
            name => Err(Error::Unknown(name.to_string())),
        }
    }
}

/// [`Part`] error.
#[derive(Debug, thiserror::Error)]
pub enum Error
{
    /// Unknown description part.
    #[error("Unknown description part '{0}'")]
    Unknown(String),

    /// Invalid paragraph.
    #[error("Invalid paragraph")]
    InvalidParagraph(#[source] ParagraphError),

    /// Invalid variable list.
    #[error("Invalid variable list")]
    InvalidVariableList(#[source] VariableListError),

    /// Invalid informal table.
    #[error("Invalid informal table")]
    InvalidInformalTable(#[source] TableError),

    /// Invalid itemized list.
    #[error("Invalid itemized list")]
    InvalidItemizedList(#[source] ItemizedListError),

    /// Invalid table.
    #[error("Invalid table")]
    InvalidTable(#[source] TableError),

    /// Invalid gloss list.
    #[error("Invalid gloss list")]
    InvalidGlossList(#[source] GlossListError),
}