tagotip_codec/
validate.rs1use crate::consts;
2use crate::error::{ParseError, ParseErrorKind};
3
4pub fn validate_varname(name: &str, pos: usize) -> Result<(), ParseError> {
6 if name.is_empty() {
7 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
8 }
9 if name.len() > consts::MAX_VARNAME_LEN {
10 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
11 }
12 for &b in name.as_bytes() {
13 if !(b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'_') {
14 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
15 }
16 }
17 Ok(())
18}
19
20pub fn validate_serial(serial: &str, pos: usize) -> Result<(), ParseError> {
22 if serial.is_empty() {
23 return Err(ParseError::new(ParseErrorKind::InvalidSerial, pos));
24 }
25 if serial.len() > consts::MAX_SERIAL_LEN {
26 return Err(ParseError::new(ParseErrorKind::InvalidSerial, pos));
27 }
28 for &b in serial.as_bytes() {
29 if !(b.is_ascii_alphanumeric() || b == b'-' || b == b'_') {
30 return Err(ParseError::new(ParseErrorKind::InvalidSerial, pos));
31 }
32 }
33 Ok(())
34}
35
36pub fn validate_group(group: &str, pos: usize) -> Result<(), ParseError> {
38 if group.is_empty() {
39 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
40 }
41 if group.len() > consts::MAX_GROUP_LEN {
42 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
43 }
44 for &b in group.as_bytes() {
45 if !(b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'_') {
46 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
47 }
48 }
49 Ok(())
50}
51
52pub fn validate_meta_key(key: &str, pos: usize) -> Result<(), ParseError> {
54 if key.is_empty() {
55 return Err(ParseError::new(ParseErrorKind::InvalidMetadata, pos));
56 }
57 if key.len() > consts::MAX_META_KEY_LEN {
58 return Err(ParseError::new(ParseErrorKind::InvalidMetadata, pos));
59 }
60 for &b in key.as_bytes() {
61 if !(b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'_') {
62 return Err(ParseError::new(ParseErrorKind::InvalidMetadata, pos));
63 }
64 }
65 Ok(())
66}
67
68pub fn validate_unit(unit: &str, pos: usize) -> Result<(), ParseError> {
70 if unit.is_empty() {
71 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
72 }
73 if unit.len() > consts::MAX_UNIT_LEN {
74 return Err(ParseError::new(ParseErrorKind::InvalidField, pos));
75 }
76 Ok(())
77}
78
79pub fn validate_number(s: &str, pos: usize) -> Result<(), ParseError> {
81 let bytes = s.as_bytes();
82 let mut i = 0;
83
84 if i < bytes.len() && bytes[i] == b'-' {
85 i += 1;
86 }
87
88 if i >= bytes.len() {
89 return Err(ParseError::new(ParseErrorKind::InvalidVariable, pos));
90 }
91
92 if bytes[i] == b'0' {
94 i += 1;
95 } else if bytes[i] >= b'1' && bytes[i] <= b'9' {
96 i += 1;
97 while i < bytes.len() && bytes[i].is_ascii_digit() {
98 i += 1;
99 }
100 } else {
101 return Err(ParseError::new(ParseErrorKind::InvalidVariable, pos));
102 }
103
104 if i < bytes.len() && bytes[i] == b'.' {
106 i += 1;
107 if i >= bytes.len() || !bytes[i].is_ascii_digit() {
108 return Err(ParseError::new(ParseErrorKind::InvalidVariable, pos));
109 }
110 while i < bytes.len() && bytes[i].is_ascii_digit() {
111 i += 1;
112 }
113 }
114
115 if i != bytes.len() {
116 return Err(ParseError::new(ParseErrorKind::InvalidVariable, pos));
117 }
118
119 Ok(())
120}