bee_block/output/feature/
metadata.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::BoundedU16, prefix::BoxedSlicePrefix};
8
9use crate::Error;
10
11pub(crate) type MetadataFeatureLength =
12    BoundedU16<{ *MetadataFeature::LENGTH_RANGE.start() }, { *MetadataFeature::LENGTH_RANGE.end() }>;
13
14/// Defines metadata, arbitrary binary data, that will be stored in the output.
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 = |err| Error::InvalidMetadataFeatureLength(err.into_prefix_err().into()))]
18pub struct MetadataFeature(
19    // Binary data.
20    BoxedSlicePrefix<u8, MetadataFeatureLength>,
21);
22
23impl TryFrom<Vec<u8>> for MetadataFeature {
24    type Error = Error;
25
26    fn try_from(data: Vec<u8>) -> Result<Self, Error> {
27        data.into_boxed_slice()
28            .try_into()
29            .map(Self)
30            .map_err(Error::InvalidMetadataFeatureLength)
31    }
32}
33
34impl MetadataFeature {
35    /// The [`Feature`](crate::output::Feature) kind of [`MetadataFeature`].
36    pub const KIND: u8 = 2;
37    /// Valid lengths for a [`MetadataFeature`].
38    pub const LENGTH_RANGE: RangeInclusive<u16> = 1..=8192;
39
40    /// Creates a new [`MetadataFeature`].
41    #[inline(always)]
42    pub fn new(data: Vec<u8>) -> Result<Self, Error> {
43        Self::try_from(data)
44    }
45
46    /// Returns the data.
47    #[inline(always)]
48    pub fn data(&self) -> &[u8] {
49        &self.0
50    }
51}
52
53impl core::fmt::Display for MetadataFeature {
54    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
55        write!(f, "{}", prefix_hex::encode(self.data()))
56    }
57}
58
59impl core::fmt::Debug for MetadataFeature {
60    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
61        write!(f, "MetadataFeature({})", 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 MetadataFeatureDto {
72        #[serde(rename = "type")]
73        pub kind: u8,
74        pub data: String,
75    }
76}