triseratops/tag/
util.rs

1// Copyright (c) 2023 Jan Holthuis <jan.holthuis@rub.de>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy
4// of the MPL was not distributed with this file, You can obtain one at
5// http://mozilla.org/MPL/2.0/.
6//
7// SPDX-License-Identifier: MPL-2.0
8
9//! Various helper utilities for simplify parsing.
10
11use super::color::Color;
12use super::generic::Version;
13use crate::error::Error;
14use crate::util::Res;
15use nom::bytes::complete::take;
16use std::io;
17
18/// Returns a `Color` struct parsed from the first 3 input bytes.
19pub fn take_color(input: &[u8]) -> Res<&[u8], Color> {
20    let (input, bytes) = nom::bytes::complete::take(3usize)(input)?;
21    let (bytes, red) = nom::number::complete::u8(bytes)?;
22    let (bytes, green) = nom::number::complete::u8(bytes)?;
23    let (_, blue) = nom::combinator::all_consuming(nom::number::complete::u8)(bytes)?;
24    Ok((input, Color { red, green, blue }))
25}
26
27#[test]
28fn test_take_color() {
29    assert_eq!(
30        take_color(&[0xFF, 0x00, 0x10]),
31        Ok((
32            &[][..],
33            Color {
34                red: 0xFF,
35                green: 0x00,
36                blue: 0x10
37            }
38        ))
39    );
40    assert_eq!(
41        take_color(&[0x11, 0x22, 0x33, 0x44]),
42        Ok((
43            &[0x44][..],
44            Color {
45                red: 0x11,
46                green: 0x22,
47                blue: 0x33
48            }
49        ))
50    );
51    assert!(take_color(&[0xAB, 0xCD]).is_err());
52}
53
54pub fn write_color(writer: &mut impl io::Write, color: Color) -> Result<usize, Error> {
55    let Color { blue, green, red } = color;
56    Ok(writer.write(&[red, green, blue])?)
57}
58
59/// Returns a `Version` struct parsed from the first 2 input bytes.
60pub fn take_version(input: &[u8]) -> Res<&[u8], Version> {
61    let (input, version) = take(2usize)(input)?;
62    Ok((
63        input,
64        Version {
65            major: version[0],
66            minor: version[1],
67        },
68    ))
69}
70
71#[test]
72fn test_take_version() {
73    assert_eq!(
74        take_version(&[0x02, 0x05]),
75        Ok((&[][..], Version { major: 2, minor: 5 }))
76    );
77    assert_eq!(
78        take_version(&[0x01, 0x02, 0x03]),
79        Ok((&[0x03][..], Version { major: 1, minor: 2 }))
80    );
81    assert!(take_version(&[0x0A]).is_err());
82}
83
84pub fn write_version(writer: &mut impl io::Write, version: Version) -> Result<usize, Error> {
85    let Version { major, minor } = version;
86    Ok(writer.write(&[major, minor])?)
87}