bee_block/output/feature/
tag.rs1use alloc::vec::Vec;
5use core::ops::RangeInclusive;
6
7use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix};
8
9use crate::Error;
10
11pub(crate) type TagFeatureLength =
12 BoundedU8<{ *TagFeature::LENGTH_RANGE.start() }, { *TagFeature::LENGTH_RANGE.end() }>;
13
14#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, packable::Packable)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17#[packable(unpack_error = Error, with = |e| Error::InvalidTagFeatureLength(e.into_prefix_err().into()))]
18pub struct TagFeature(
19 BoxedSlicePrefix<u8, TagFeatureLength>,
21);
22
23impl TryFrom<Vec<u8>> for TagFeature {
24 type Error = Error;
25
26 fn try_from(tag: Vec<u8>) -> Result<Self, Error> {
27 tag.into_boxed_slice()
28 .try_into()
29 .map(Self)
30 .map_err(Error::InvalidTagFeatureLength)
31 }
32}
33
34impl TagFeature {
35 pub const KIND: u8 = 3;
37 pub const LENGTH_RANGE: RangeInclusive<u8> = 1..=64;
39
40 #[inline(always)]
42 pub fn new(tag: Vec<u8>) -> Result<Self, Error> {
43 Self::try_from(tag)
44 }
45
46 #[inline(always)]
48 pub fn tag(&self) -> &[u8] {
49 &self.0
50 }
51}
52
53impl core::fmt::Display for TagFeature {
54 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
55 write!(f, "{}", prefix_hex::encode(self.tag()))
56 }
57}
58
59impl core::fmt::Debug for TagFeature {
60 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
61 write!(f, "TagFeature({})", self)
62 }
63}
64
65#[cfg(feature = "dto")]
66#[allow(missing_docs)]
67pub mod dto {
68 use serde::{Deserialize, Serialize};
69
70 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
71 pub struct TagFeatureDto {
72 #[serde(rename = "type")]
73 pub kind: u8,
74 pub tag: String,
75 }
76}