calcify/tree/branch/
mod.rs

1use std::error;
2use std::f64;
3
4mod collection;
5pub use collection::Collection;
6pub use collection::Bin;
7pub use collection::Point;
8pub use collection::PointBin;
9use crate::four_mat::FourVec;
10use crate::four_mat::FourMat;
11
12use crate::three_mat::ThreeMat;
13use crate::three_mat::ThreeVec;
14
15use crate::utils;
16use utils::{Serializable, Deserializable};
17use utils::errors::CalcifyError;
18
19extern crate rmp;
20use rmp::encode::*;
21use rmp::decode::*;
22
23
24/// Branch
25///
26/// # Note
27///
28/// * **Not intended for direct use. Use the memebers of Tree instead.**
29pub struct Branch {
30    subtype: String,
31    branch: Box<dyn Serializable>,
32    buffer: Option<Vec<u8>>,
33}
34
35impl Branch{
36    pub fn new(subtype: String, branch: Box<dyn Serializable>) -> Branch{
37        let buffer: Option<Vec<u8>> = None;
38        Branch {
39            subtype,
40            branch,
41            buffer,
42        }
43    }
44    /// Returns a Collection of the specified subtype from the Branch
45    ///
46    pub fn extract<T: Serializable + Deserializable>(&mut self) -> Result<Collection<T>, Box<dyn error::Error>> {
47        if self.buffer.is_none() {
48            self.buffer = Some(self.branch.to_msg()?);
49        }
50        if let Ok((out, _)) = Collection::<T>::from_msg(&mut self.buffer.as_ref().unwrap()){
51            return Ok(out);
52        }
53        Err(Box::new(CalcifyError::ParseError))
54    }
55}
56
57impl Serializable for Branch {
58    fn to_json(&self) -> String {
59        format!("{{\"subtype\":{},\"branch\":{}}}",self.subtype.to_json(),self.branch.to_json())
60    }
61
62    fn to_msg(&self) -> Result<Vec<u8>, ValueWriteError> {
63        let mut buf = Vec::new();
64        write_map_len(&mut buf, 2)?;
65        write_str(&mut buf, "subtype")?;
66        buf.append(&mut self.subtype.to_msg()?);
67        write_str(&mut buf, "branch")?;
68        buf.append(&mut self.branch.to_msg()?);
69        Ok(buf)
70    }
71}
72
73impl Deserializable for Branch {
74    fn from_json(s: &str) -> Result<Self, Box<dyn error::Error>> {
75        let mut subtype: &str = "";
76        let mut branch_str: &str = "";
77        let pattern: Vec<char> = "{\"subtype\":}".chars().collect();
78        for (i,dim) in s.trim_matches(|p| pattern.contains(&p)).split(",\"branch\":").enumerate() {
79            match i {
80                0 => subtype = dim.trim_matches(|p| p == '\"'),
81                1 => branch_str = dim,
82                _ => return Err(Box::new(CalcifyError::ParseError)),
83            }
84        }
85        let branch: Box<dyn Serializable> = match subtype {
86            "f64" => Box::new(Collection::<f64>::from_json(&branch_str)?),
87            "ThreeVec" => Box::new(Collection::<ThreeVec>::from_json(&branch_str)?),
88            "ThreeMat" => Box::new(Collection::<ThreeMat>::from_json(&branch_str)?),
89            "FourVec" => Box::new(Collection::<FourVec>::from_json(&branch_str)?),
90            "FourMat" => Box::new(Collection::<FourMat>::from_json(&branch_str)?),
91            "Bin" => Box::new(Collection::<Bin>::from_json(&branch_str)?),
92            "Point" => Box::new(Collection::<Point>::from_json(&branch_str)?),
93            "PointBin" => Box::new(Collection::<PointBin>::from_json(&branch_str)?),
94            _ => return Err(Box::new(CalcifyError::ParseError)),
95        };
96        Ok(Branch::new(subtype.to_string(),branch))
97    }
98
99    fn from_msg(mut bytes: &[u8]) -> Result<(Self,&[u8]), Box<dyn error::Error>> {
100
101        if let Ok(_len) = read_map_len(&mut bytes) {
102            let mut unparsed = &bytes[..];
103            if let Ok((_,rest)) = read_str_from_slice(unparsed) {
104                unparsed = rest;
105                if let Ok((subtype,rest)) = read_str_from_slice(unparsed) {
106                    unparsed = rest;
107                    if let Ok((_,rest)) = read_str_from_slice(unparsed) {
108                        unparsed = rest;
109                        let (branch,rest): (Box<dyn Serializable>,&[u8])  = match subtype {
110                            "f64" => {
111                                if let Ok((ot,rest)) = Collection::<f64>::from_msg(unparsed) {
112                                    (Box::new(ot),rest)
113                                } else {
114                                    return Err(Box::new(CalcifyError::ParseError));
115                                }
116                            },
117                            "ThreeVec" => {
118                                if let Ok((ot,rest)) = Collection::<ThreeVec>::from_msg(unparsed) {
119                                    (Box::new(ot),rest)
120                                } else {
121                                    return Err(Box::new(CalcifyError::ParseError));
122                                }
123                            },
124                            "ThreeMat" => {
125                                if let Ok((ot,rest)) = Collection::<ThreeMat>::from_msg(unparsed) {
126                                    (Box::new(ot),rest)
127                                } else {
128                                    return Err(Box::new(CalcifyError::ParseError));
129                                }
130                            },
131                            "FourVec" => {
132                                if let Ok((ot,rest)) = Collection::<FourVec>::from_msg(unparsed) {
133                                    (Box::new(ot),rest)
134                                } else {
135                                    return Err(Box::new(CalcifyError::ParseError));
136                                }
137                            },
138                            "FourMat" => {
139                                if let Ok((ot,rest)) = Collection::<FourMat>::from_msg(unparsed) {
140                                    (Box::new(ot),rest)
141                                } else {
142                                    return Err(Box::new(CalcifyError::ParseError));
143                                }
144                            },
145                            "Bin" => {
146                                if let Ok((ot,rest)) = Collection::<Bin>::from_msg(&mut bytes) {
147                                    (Box::new(ot),rest)
148                                } else {
149                                    return Err(Box::new(CalcifyError::ParseError));
150                                }
151                            },
152                            "Point" => {
153                                if let Ok((ot,rest)) = Collection::<Point>::from_msg(&mut bytes) {
154                                    (Box::new(ot),rest)
155                                } else {
156                                    return Err(Box::new(CalcifyError::ParseError));
157                                }
158                            },
159                            "PointBin" => {
160                                if let Ok((ot,rest)) = Collection::<PointBin>::from_msg(&mut bytes) {
161                                    (Box::new(ot),rest)
162                                } else {
163                                    return Err(Box::new(CalcifyError::ParseError));
164                                }
165                            },
166                            "Object" => {
167                                return Err(Box::new(CalcifyError::ObjectBranchDeserializeError));
168                            },
169                            _ => return Err(Box::new(CalcifyError::ParseError)),
170                        };
171                        return Ok((Branch::new(subtype.to_string(),branch),rest));
172                    }
173                }
174            }
175        }
176        Err(Box::new(CalcifyError::ParseError))
177    }
178}