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
use super::*;

/// A single statement, made up by variables.
#[derive(Debug, Clone)]
pub struct Statement<Var>
    where Var: VariableFormat
{
    pub parts: Vec<Var>,
}

impl<Var> Statement<Var>
    where Var: VariableFormat
{
    pub fn new() -> Statement<Var> {
        Statement { parts: Vec::new() }
    }

    pub fn push<V>(&mut self, variable: V)
        where V: Into<Var>
    {
        self.parts.push(variable.into());
    }

    pub fn join<A>(self, separator: A) -> Statement<Var>
        where A: Into<Var> + Clone
    {
        let mut it = self.parts.into_iter();

        let part: Var = match it.next() {
            Some(part) => part,
            None => return Statement::new(),
        };

        let mut parts: Vec<Var> = Vec::new();
        parts.push(part);

        while let Some(part) = it.next() {
            parts.push(separator.clone().into());
            parts.push(part);
        }

        Statement { parts: parts }
    }

    pub fn format<E>(&self, out: &mut E, depth: usize, extra: &mut Var::Extra) -> Result<()>
        where E: ElementFormat
    {
        for part in &self.parts {
            part.format(out, depth, extra)?;
        }

        Ok(())
    }
}

impl<'a, T, Var> From<&'a T> for Statement<Var>
    where T: Into<Statement<Var>> + Clone,
          Var: VariableFormat
{
    fn from(value: &'a T) -> Statement<Var> {
        value.clone().into()
    }
}

impl<S, Var> From<Vec<S>> for Statement<Var>
    where Var: VariableFormat,
          S: Into<Var>
{
    fn from(values: Vec<S>) -> Statement<Var> {
        let mut s = Statement::new();

        for value in values {
            s.push(value);
        }

        s
    }
}

impl<Var> From<Statement<Var>> for Element<Var>
    where Var: VariableFormat
{
    fn from(value: Statement<Var>) -> Element<Var> {
        Element::Push(value)
    }
}

impl<Var> From<String> for Statement<Var>
    where Var: From<String> + VariableFormat
{
    fn from(value: String) -> Statement<Var> {
        Statement { parts: vec![value.into()] }
    }
}