matc/clusters/codec/
json_util.rs

1// Helper functions for extracting typed values from serde_json::Value objects
2// used by the generated encode_command_json functions.
3
4use anyhow;
5
6pub fn get_u8(args: &serde_json::Value, name: &str) -> anyhow::Result<u8> {
7    args.get(name)
8        .and_then(|v| v.as_u64())
9        .map(|n| n as u8)
10        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
11}
12
13pub fn get_u16(args: &serde_json::Value, name: &str) -> anyhow::Result<u16> {
14    args.get(name)
15        .and_then(|v| v.as_u64())
16        .map(|n| n as u16)
17        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
18}
19
20pub fn get_u32(args: &serde_json::Value, name: &str) -> anyhow::Result<u32> {
21    args.get(name)
22        .and_then(|v| v.as_u64())
23        .map(|n| n as u32)
24        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
25}
26
27pub fn get_u64(args: &serde_json::Value, name: &str) -> anyhow::Result<u64> {
28    args.get(name)
29        .and_then(|v| v.as_u64())
30        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
31}
32
33pub fn get_i8(args: &serde_json::Value, name: &str) -> anyhow::Result<i8> {
34    args.get(name)
35        .and_then(|v| v.as_i64())
36        .map(|n| n as i8)
37        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
38}
39
40pub fn get_i16(args: &serde_json::Value, name: &str) -> anyhow::Result<i16> {
41    args.get(name)
42        .and_then(|v| v.as_i64())
43        .map(|n| n as i16)
44        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
45}
46
47pub fn get_i32(args: &serde_json::Value, name: &str) -> anyhow::Result<i32> {
48    args.get(name)
49        .and_then(|v| v.as_i64())
50        .map(|n| n as i32)
51        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
52}
53
54pub fn get_i64(args: &serde_json::Value, name: &str) -> anyhow::Result<i64> {
55    args.get(name)
56        .and_then(|v| v.as_i64())
57        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
58}
59
60pub fn get_bool(args: &serde_json::Value, name: &str) -> anyhow::Result<bool> {
61    args.get(name)
62        .and_then(|v| v.as_bool())
63        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
64}
65
66pub fn get_string(args: &serde_json::Value, name: &str) -> anyhow::Result<String> {
67    args.get(name)
68        .and_then(|v| v.as_str())
69        .map(|s| s.to_string())
70        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))
71}
72
73// Accepts a hex string and decodes it to bytes.
74pub fn get_octstr(args: &serde_json::Value, name: &str) -> anyhow::Result<Vec<u8>> {
75    let s = args.get(name)
76        .and_then(|v| v.as_str())
77        .ok_or_else(|| anyhow::anyhow!("missing or invalid field: {}", name))?;
78    let s = s.replace(' ', "");
79    hex::decode(&s).map_err(|e| anyhow::anyhow!("field {}: invalid hex: {}", name, e))
80}
81
82// Optional variants - return None when the field is absent or null.
83pub fn get_opt_u8(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<u8>> {
84    match args.get(name) {
85        None | Some(serde_json::Value::Null) => Ok(None),
86        Some(v) => v.as_u64()
87            .map(|n| Some(n as u8))
88            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
89    }
90}
91
92pub fn get_opt_u16(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<u16>> {
93    match args.get(name) {
94        None | Some(serde_json::Value::Null) => Ok(None),
95        Some(v) => v.as_u64()
96            .map(|n| Some(n as u16))
97            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
98    }
99}
100
101pub fn get_opt_u32(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<u32>> {
102    match args.get(name) {
103        None | Some(serde_json::Value::Null) => Ok(None),
104        Some(v) => v.as_u64()
105            .map(|n| Some(n as u32))
106            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
107    }
108}
109
110pub fn get_opt_u64(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<u64>> {
111    match args.get(name) {
112        None | Some(serde_json::Value::Null) => Ok(None),
113        Some(v) => v.as_u64()
114            .map(Some)
115            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
116    }
117}
118
119pub fn get_opt_i8(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<i8>> {
120    match args.get(name) {
121        None | Some(serde_json::Value::Null) => Ok(None),
122        Some(v) => v.as_i64()
123            .map(|n| Some(n as i8))
124            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
125    }
126}
127
128pub fn get_opt_i16(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<i16>> {
129    match args.get(name) {
130        None | Some(serde_json::Value::Null) => Ok(None),
131        Some(v) => v.as_i64()
132            .map(|n| Some(n as i16))
133            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
134    }
135}
136
137pub fn get_opt_i32(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<i32>> {
138    match args.get(name) {
139        None | Some(serde_json::Value::Null) => Ok(None),
140        Some(v) => v.as_i64()
141            .map(|n| Some(n as i32))
142            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
143    }
144}
145
146pub fn get_opt_i64(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<i64>> {
147    match args.get(name) {
148        None | Some(serde_json::Value::Null) => Ok(None),
149        Some(v) => v.as_i64()
150            .map(Some)
151            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
152    }
153}
154
155pub fn get_opt_bool(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<bool>> {
156    match args.get(name) {
157        None | Some(serde_json::Value::Null) => Ok(None),
158        Some(v) => v.as_bool()
159            .map(Some)
160            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
161    }
162}
163
164pub fn get_opt_string(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<String>> {
165    match args.get(name) {
166        None | Some(serde_json::Value::Null) => Ok(None),
167        Some(v) => v.as_str()
168            .map(|s| Some(s.to_string()))
169            .ok_or_else(|| anyhow::anyhow!("invalid field: {}", name)),
170    }
171}
172
173pub fn get_opt_octstr(args: &serde_json::Value, name: &str) -> anyhow::Result<Option<Vec<u8>>> {
174    match args.get(name) {
175        None | Some(serde_json::Value::Null) => Ok(None),
176        Some(v) => {
177            let s = v.as_str().ok_or_else(|| anyhow::anyhow!("invalid field: {}", name))?;
178            let s = s.replace(' ', "");
179            hex::decode(&s)
180                .map(Some)
181                .map_err(|e| anyhow::anyhow!("field {}: invalid hex: {}", name, e))
182        }
183    }
184}