bee_block/output/feature/
tag.rs

1// Copyright 2021-2022 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use 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/// Makes it possible to tag outputs with an index, so they can be retrieved through an indexer API.
15#[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    // Binary tag.
20    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    /// The [`Feature`](crate::output::Feature) kind of an [`TagFeature`].
36    pub const KIND: u8 = 3;
37    /// Valid lengths for an [`TagFeature`].
38    pub const LENGTH_RANGE: RangeInclusive<u8> = 1..=64;
39
40    /// Creates a new [`TagFeature`].
41    #[inline(always)]
42    pub fn new(tag: Vec<u8>) -> Result<Self, Error> {
43        Self::try_from(tag)
44    }
45
46    /// Returns the tag.
47    #[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}