acter/api/
utils.rs

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use matrix_sdk_ui::eyeball_im::VectorDiff;

pub struct ApiVectorDiff<T> {
    action: String,
    values: Option<Vec<T>>,
    index: Option<usize>,
    value: Option<T>,
}

impl<T> ApiVectorDiff<T>
where
    T: Clone,
{
    pub fn action(&self) -> String {
        self.action.clone()
    }

    pub fn values(&self) -> Option<Vec<T>> {
        match self.action.as_str() {
            "Append" | "Reset" => self.values.clone(),
            _ => None,
        }
    }

    pub fn index(&self) -> Option<usize> {
        match self.action.as_str() {
            "Insert" | "Set" | "Remove" => self.index,
            _ => None,
        }
    }

    pub fn value(&self) -> Option<T> {
        match self.action.as_str() {
            "Insert" | "Set" | "PushBack" | "PushFront" => self.value.clone(),
            _ => None,
        }
    }
}

impl<T> ApiVectorDiff<T> {
    pub fn current_items(values: Vec<T>) -> Self {
        ApiVectorDiff {
            action: "Reset".to_string(),
            values: Some(values),
            index: None,
            value: None,
        }
    }
}

pub fn remap_for_diff<E, T, C>(diff: VectorDiff<E>, mapper: C) -> ApiVectorDiff<T>
where
    C: Fn(E) -> T,
    T: Clone,
    E: Clone,
{
    match diff {
        // Append the given elements at the end of the `Vector` and notify subscribers
        VectorDiff::Append { values } => ApiVectorDiff {
            action: "Append".to_string(),
            values: Some(values.into_iter().map(mapper).collect()),
            index: None,
            value: None,
        },
        // Insert an element at the given position and notify subscribers
        VectorDiff::Insert { index, value } => ApiVectorDiff {
            action: "Insert".to_string(),
            values: None,
            index: Some(index),
            value: Some(mapper(value)),
        },
        // Replace the element at the given position, notify subscribers and return the previous element at that position
        VectorDiff::Set { index, value } => ApiVectorDiff {
            action: "Set".to_string(),
            values: None,
            index: Some(index),
            value: Some(mapper(value)),
        },
        // Remove the element at the given position, notify subscribers and return the element
        VectorDiff::Remove { index } => ApiVectorDiff {
            action: "Remove".to_string(),
            values: None,
            index: Some(index),
            value: None,
        },
        // Add an element at the back of the list and notify subscribers
        VectorDiff::PushBack { value } => ApiVectorDiff {
            action: "PushBack".to_string(),
            values: None,
            index: None,
            value: Some(mapper(value)),
        },
        // Add an element at the front of the list and notify subscribers
        VectorDiff::PushFront { value } => ApiVectorDiff {
            action: "PushFront".to_string(),
            values: None,
            index: None,
            value: Some(mapper(value)),
        },
        // Remove the last element, notify subscribers and return the element
        VectorDiff::PopBack => ApiVectorDiff {
            action: "PopBack".to_string(),
            values: None,
            index: None,
            value: None,
        },
        // Remove the first element, notify subscribers and return the element
        VectorDiff::PopFront => ApiVectorDiff {
            action: "PopFront".to_string(),
            values: None,
            index: None,
            value: None,
        },
        // Clear out all of the elements in this `Vector` and notify subscribers
        VectorDiff::Clear => ApiVectorDiff {
            action: "Clear".to_string(),
            values: None,
            index: None,
            value: None,
        },
        VectorDiff::Reset { values } => ApiVectorDiff {
            action: "Reset".to_string(),
            values: Some(values.into_iter().map(mapper).collect()),
            index: None,
            value: None,
        },
        // Truncate the vector to `len` elements and notify subscribers
        VectorDiff::Truncate { length } => ApiVectorDiff {
            action: "Truncate".to_string(),
            values: None,
            index: Some(length),
            value: None,
        },
    }
}

pub struct VecStringBuilder(pub(crate) Vec<String>);

impl Default for VecStringBuilder {
    fn default() -> Self {
        Self::new()
    }
}

impl VecStringBuilder {
    pub fn new() -> VecStringBuilder {
        VecStringBuilder(Vec::new())
    }
    pub fn add(&mut self, v: String) {
        self.0.push(v);
    }
}

pub fn new_vec_string_builder() -> VecStringBuilder {
    VecStringBuilder::new()
}