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
|
// -*- coding: utf-8 -*-
//
// Copyright (C) 2024 Michael Büsch <m@bues.ch>
//
// Licensed under the Apache License version 2.0
// or the MIT license, at your option.
// SPDX-License-Identifier: Apache-2.0 OR MIT
use anyhow::{self as ah, format_err as err};
use std::time::Duration;
pub fn parse_bool(s: &str) -> ah::Result<bool> {
let s = s.to_lowercase();
let s = s.trim();
match s {
"true" | "1" | "yes" | "on" => Ok(true),
"false" | "0" | "no" | "off" => Ok(false),
_ => Err(err!("Invalid boolean string")),
}
}
pub fn parse_u16(s: &str) -> ah::Result<u16> {
let s = s.trim();
if let Some(s) = s.strip_prefix("0x") {
Ok(u16::from_str_radix(s, 16)?)
} else {
Ok(s.parse::<u16>()?)
}
}
fn parse_u32(s: &str) -> ah::Result<u32> {
let s = s.trim();
if let Some(s) = s.strip_prefix("0x") {
Ok(u32::from_str_radix(s, 16)?)
} else {
Ok(s.parse::<u32>()?)
}
}
fn parse_f64(s: &str) -> ah::Result<f64> {
let s = s.trim();
let value = s.parse::<f64>()?;
if value.is_finite() {
Ok(value)
} else {
Err(err!("Invalid floating point value (Inf or NaN)"))
}
}
fn parse_hexdigit(s: &str) -> ah::Result<u8> {
assert_eq!(s.len(), 1);
Ok(u8::from_str_radix(s, 16)?)
}
pub fn parse_hex<const SIZE: usize>(s: &str) -> ah::Result<[u8; SIZE]> {
let s = s.trim();
if !s.is_ascii() {
return Err(err!("Hex string contains invalid characters."));
}
let len = s.len();
if len != SIZE * 2 {
return Err(err!(
"Hex string is too short: Expected {}, got {} chars",
SIZE * 2,
len,
));
}
let mut ret = [0; SIZE];
for i in 0..SIZE {
ret[i] = parse_hexdigit(&s[i * 2..i * 2 + 1])? << 4;
ret[i] |= parse_hexdigit(&s[i * 2 + 1..i * 2 + 2])?;
}
Ok(ret)
}
pub fn parse_duration(s: &str) -> ah::Result<Duration> {
if let Ok(secs) = parse_u32(s) {
return Ok(Duration::from_secs(secs.into()));
}
if let Ok(secs) = parse_f64(s) {
if secs >= 0.0 && secs <= u32::MAX.into() {
return Ok(Duration::from_secs_f64(secs));
}
}
Err(err!("Invalid Duration"))
}
// vim: ts=4 sw=4 expandtab
|