use std::io::{Read, Write};
use crate::{
common::traits::private::Sealed,
v0::{
config::Config,
metadata::{
error::{
MetadataIdentifierOutOfRangeError, MetadataRecordReadError,
MetadataRecordWriteError,
},
traits::MetadataRecordObj,
},
raw::VariableLengthEnum,
tokens::{error::MetadataTokenError, MetadataToken},
traits::{ReadFrom, WriteTo},
},
};
use super::ReservedMetadataRecord;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CustomReservedMetadataRecordObj {
pub(crate) identifier: u32,
data: Vec<u8>,
}
impl Sealed for CustomReservedMetadataRecordObj {}
impl MetadataRecordObj for CustomReservedMetadataRecordObj {
fn token(&self) -> Result<MetadataToken, MetadataTokenError> {
Ok(MetadataToken::ReservedOfficial(self.identifier))
}
fn byte_length(&self) -> usize {
self.data.len()
}
}
impl CustomReservedMetadataRecordObj {
pub(crate) fn read_from<C: ?Sized + Config, R: ?Sized + Read>(
reader: &mut R,
configuration: &C,
identifier: u32,
) -> Result<Self, MetadataRecordReadError> {
let length: usize = VariableLengthEnum::read_from(reader, configuration)?.try_into()?;
let mut data = Vec::with_capacity(length);
reader.take(length as u64).read_to_end(&mut data)?;
Ok(Self { identifier, data })
}
}
impl<W: ?Sized + Write> WriteTo<W> for CustomReservedMetadataRecordObj {
type WriteError = MetadataRecordWriteError;
fn write_to<C: ?Sized + Config>(
&self,
writer: &mut W,
configuration: &C,
) -> Result<(), Self::WriteError> {
VariableLengthEnum::from(self.data.len()).write_to(writer, configuration)?;
writer.write_all(&self.data)?;
Ok(())
}
}
impl CustomReservedMetadataRecordObj {
pub fn new(identifier: u32, data: Vec<u8>) -> Result<Self, MetadataIdentifierOutOfRangeError> {
if !(0x100000u32..0x1FFFFFu32).contains(&identifier) {
return Err(MetadataIdentifierOutOfRangeError::custom_key(identifier));
}
Ok(Self { identifier, data })
}
pub fn identifier(&self) -> u32 {
self.identifier
}
pub fn data(&self) -> &[u8] {
&self.data
}
}
impl Into<ReservedMetadataRecord> for CustomReservedMetadataRecordObj {
fn into(self) -> ReservedMetadataRecord {
ReservedMetadataRecord::Custom(self)
}
}