1use std::{
2 collections::BTreeMap,
3 iter::{empty, once},
4 str::FromStr,
5};
6
7use nom::{
8 branch::alt,
9 character::complete::{char, digit1},
10 combinator::{map_res, opt, recognize},
11 error::VerboseError,
12 multi::many1,
13 sequence::tuple,
14 IResult,
15};
16use num_bigint::BigInt;
17
18use crate::error::ConversionError;
19
20pub fn singleton<T, C>(value: T) -> C
22where
23 C: FromIterator<T>,
24{
25 once(value).collect()
26}
27
28pub fn none<T, C>() -> C
30where
31 C: FromIterator<T>,
32{
33 empty::<T>().collect()
34}
35
36pub fn union_btree_maps_with<K: Clone + Ord, V: Clone, F: Fn(V, V) -> V>(
38 f: F,
39 l: BTreeMap<K, V>,
40 r: BTreeMap<K, V>,
41) -> BTreeMap<K, V> {
42 r.into_iter().fold(l.clone(), |mut acc, (k, vr)| {
43 let v = if let Some((_, vl)) = acc.remove_entry(&k) {
44 f(vl, vr)
45 } else {
46 vr
47 };
48 acc.insert(k, v);
49 acc
50 })
51}
52
53pub fn union_b_tree_maps_with<const N: usize, K: Clone + Ord, V: Clone, F: Fn(&V, &V) -> V>(
54 f: F,
55 maps: [&BTreeMap<K, V>; N],
56) -> BTreeMap<K, V> {
57 maps.into_iter().fold(BTreeMap::new(), |acc, m| {
58 m.iter().fold(acc, |mut acc, (k, v)| {
59 acc.entry(k.clone())
60 .and_modify(|va: &mut V| *va = f(va, v))
61 .or_insert(v.clone());
62
63 acc
64 })
65 })
66}
67
68pub(crate) fn guard_bytes(
70 ctx: &str,
71 bytes: Vec<u8>,
72 expected: usize,
73) -> Result<Vec<u8>, ConversionError> {
74 if bytes.len() == expected {
75 Ok(bytes)
76 } else {
77 Err(ConversionError::invalid_bytestring_length(
78 ctx, expected, "equal to", &bytes,
79 ))
80 }
81}
82
83pub(crate) fn big_int(i: &str) -> IResult<&str, BigInt, VerboseError<&str>> {
86 map_res(
87 recognize(tuple((opt(alt((char('-'), char('+')))), many1(digit1)))),
88 |s: &str| BigInt::from_str(s),
89 )(i)
90}