signalk/
design.rs

1use crate::definitions::V1StringValue;
2use crate::{V1CommonValueFields, V1NumberValue};
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
6#[serde(rename_all = "camelCase")]
7pub struct V1Design {
8    pub displacement: Option<V1NumberValue>,
9    pub ais_ship_type: Option<V1DesignAisShipType>,
10    pub draft: Option<V1DesignDraft>,
11    pub length: Option<V1DesignLength>,
12    pub keel: Option<V1DesignKeel>,
13    pub beam: Option<V1NumberValue>,
14    pub air_height: Option<V1NumberValue>,
15    pub rigging: Option<V1DesignRigging>,
16}
17
18impl V1Design {
19    pub fn update(&mut self, path: &mut Vec<&str>, value: &serde_json::value::Value) {
20        if path.is_empty() {
21            return;
22        }
23        match path[0] {
24            "displacement" => self.displacement = V1NumberValue::from_value(value),
25            "aisShipType" => self.ais_ship_type = V1DesignAisShipType::from_value(value),
26            "draft" => self.draft = V1DesignDraft::from_value(value),
27            "length" => self.length = V1DesignLength::from_value(value),
28            "keel" => self.keel = V1DesignKeel::from_value(value),
29            "beam" => self.beam = V1NumberValue::from_value(value),
30            "airHeight" => self.air_height = V1NumberValue::from_value(value),
31            "rigging" => self.rigging = V1DesignRigging::from_value(value),
32            &_ => {
33                log::warn!("V1Design: Unknown update pattern: {:?}::{:?}", path, value);
34            }
35        }
36    }
37}
38
39#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
40#[serde(rename_all = "camelCase")]
41pub struct V1DesignAisShipType {
42    pub value: Option<V1DesignAisShipTypeValue>,
43    #[serde(flatten)]
44    pub common_value_fields: Option<V1CommonValueFields>,
45}
46
47impl V1DesignAisShipType {
48    pub fn from_value(value: &serde_json::value::Value) -> Option<Self> {
49        if value.is_null() {
50            None
51        } else {
52            let ship_type_result: Result<Self, serde_json::Error> =
53                serde_json::from_value(value.clone());
54            if let Ok(ship_type_value) = ship_type_result {
55                Some(ship_type_value)
56            } else {
57                None
58            }
59        }
60    }
61}
62
63#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
64#[serde(rename_all = "camelCase")]
65pub struct V1DesignAisShipTypeValue {
66    pub id: i64,
67    pub name: String,
68}
69
70#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
71#[serde(rename_all = "camelCase")]
72pub struct V1DesignDraft {
73    pub value: Option<V1DesignDraftValue>,
74    #[serde(flatten)]
75    pub common_value_fields: Option<V1CommonValueFields>,
76}
77
78impl V1DesignDraft {
79    pub fn from_value(value: &serde_json::value::Value) -> Option<Self> {
80        if value.is_null() {
81            None
82        } else {
83            let draft_result: Result<V1DesignDraft, serde_json::Error> =
84                serde_json::from_value(value.clone());
85            if let Ok(draft_value) = draft_result {
86                Some(draft_value)
87            } else {
88                None
89            }
90        }
91    }
92}
93
94#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
95#[serde(rename_all = "camelCase")]
96pub struct V1DesignDraftValue {
97    pub minimum: Option<f64>,
98    pub maximum: Option<f64>,
99    pub current: Option<f64>,
100    pub canoe: Option<f64>,
101}
102
103#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
104#[serde(rename_all = "camelCase")]
105pub struct V1DesignLength {
106    pub value: Option<V1DesignLengthValue>,
107    #[serde(flatten)]
108    pub common_value_fields: Option<V1CommonValueFields>,
109}
110
111impl V1DesignLength {
112    pub fn from_value(value: &serde_json::value::Value) -> Option<Self> {
113        if value.is_null() {
114            None
115        } else {
116            let length_result: Result<Self, serde_json::Error> =
117                serde_json::from_value(value.clone());
118            if let Ok(length_value) = length_result {
119                Some(length_value)
120            } else {
121                None
122            }
123        }
124    }
125}
126
127#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
128#[serde(rename_all = "camelCase")]
129pub struct V1DesignLengthValue {
130    pub overall: Option<f64>,
131    pub hull: Option<f64>,
132    pub waterline: Option<f64>,
133}
134
135#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
136#[serde(rename_all = "camelCase")]
137pub struct V1DesignKeel {
138    #[serde(rename = "type")]
139    pub type_: Option<V1DesignKeelType>,
140    pub angle: Option<V1NumberValue>,
141    pub lift: Option<V1NumberValue>,
142    #[serde(flatten)]
143    pub common_value_fields: Option<V1CommonValueFields>,
144}
145impl V1DesignKeel {
146    pub fn from_value(value: &serde_json::value::Value) -> Option<Self> {
147        if value.is_null() {
148            None
149        } else {
150            let keel_result: Result<Self, serde_json::Error> =
151                serde_json::from_value(value.clone());
152            if let Ok(keel_value) = keel_result {
153                Some(keel_value)
154            } else {
155                None
156            }
157        }
158    }
159}
160
161#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
162#[serde(rename_all = "lowercase")]
163pub enum V1DesignKeelType {
164    #[default]
165    Long,
166    Fin,
167    Flare,
168    Bulb,
169    Wing,
170    Centerboard,
171    Kanting,
172    Lifting,
173    Daggerboard,
174}
175
176#[derive(Serialize, Deserialize, PartialEq, Debug, Default, Clone)]
177#[serde(rename_all = "camelCase")]
178pub struct V1DesignRigging {
179    #[serde(rename = "type")]
180    pub type_: Option<V1StringValue>,
181    pub masts: Option<V1NumberValue>,
182    #[serde(flatten)]
183    pub common_value_fields: Option<V1CommonValueFields>,
184}
185
186impl V1DesignRigging {
187    pub fn from_value(value: &serde_json::value::Value) -> Option<Self> {
188        if value.is_null() {
189            None
190        } else {
191            let keel_result: Result<Self, serde_json::Error> =
192                serde_json::from_value(value.clone());
193            if let Ok(keel_value) = keel_result {
194                Some(keel_value)
195            } else {
196                None
197            }
198        }
199    }
200}