You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

106 lines
2.5 KiB

use super::errors::CodecError;
use serde::Serialize;
use std::num::ParseIntError;
use std::ops::Deref;
use std::u64;
/// A number encoded as a sequence of words
#[derive(Debug, Clone, Serialize)]
pub struct EncodedPart {
pub value: u64,
pub words: Vec<String>,
}
/// A way (variant) to split input number
pub type EncodedSplit = Vec<EncodedPart>;
/// A number encoded as words, split in multiple ways
#[derive(Debug, Clone, Serialize)]
pub struct EncodedValue(Vec<EncodedSplit>);
impl EncodedValue {
pub fn new(data: Vec<EncodedSplit>) -> Self {
EncodedValue(data)
}
}
impl Deref for EncodedValue {
type Target = Vec<EncodedSplit>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// The number value can be encoded as many word sets,
/// but decoded as one number. For partial values
/// and dictionary words (reasonable length), we can use
/// u64 (20-digit number), but the whole input text can
/// be longer than 20 digits, so we operate on String (<= 255).
#[derive(Debug, Serialize, Clone, PartialEq, Eq)]
pub struct DecodedValue(String);
impl DecodedValue {
pub fn new(value: String) -> Result<Self, CodecError> {
if value.len() > u8::MAX as usize {
Err(CodecError::TextTooLong(value.len()))
} else {
Ok(Self(value))
}
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn parse(&self) -> Result<u64, ParseIntError> {
self.0.parse()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn value_len(&self) -> Result<DecodedLength, CodecError> {
if self.len() == 0 {
return Err(CodecError::EmptyValue);
}
DecodedLength::try_from(self.len())
}
}
impl PartialEq<&str> for DecodedValue {
fn eq(&self, other: &&str) -> bool {
&self.0 == *other
}
}
impl PartialEq<DecodedValue> for &str {
fn eq(&self, other: &DecodedValue) -> bool {
*self == &other.0
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct DecodedLength(u8);
impl DecodedLength {
pub const fn from(value: u8) -> Self {
Self(value)
}
}
impl TryFrom<usize> for DecodedLength {
type Error = CodecError;
fn try_from(value: usize) -> Result<Self, CodecError> {
if value > u8::MAX as usize {
Err(CodecError::ValueLimitExceeded(value))
} else {
Ok(Self(value as u8))
}
}
}