#![recursion_limit = "256"]
#![deny(
non_upper_case_globals,
non_camel_case_types,
non_snake_case,
unused_mut,
unused_imports,
dead_code,
//missing_docs
)]
#[cfg(feature = "derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate strict_encoding_derive as derive;
pub use derive::{StrictDecode, StrictEncode};
#[allow(unused_imports)]
#[macro_use]
extern crate amplify;
#[macro_use]
extern crate amplify_derive;
#[macro_use]
mod macros;
#[macro_use]
pub mod test_helpers;
mod bitcoin;
mod byte_str;
mod collections;
#[cfg(feature = "crypto")]
mod crypto;
#[cfg(feature = "miniscript")]
mod miniscript;
pub mod net;
mod primitives;
pub mod strategies;
pub use strategies::Strategy;
pub use ::bitcoin::consensus::encode::{ReadExt, WriteExt};
use amplify::IoError;
use core::ops::Range;
use std::fmt;
use std::io;
pub trait StrictEncode {
fn strict_encode<E: io::Write>(&self, e: E) -> Result<usize, Error>;
fn strict_serialize(&self) -> Result<Vec<u8>, Error> {
let mut e = vec![];
let _ = self.strict_encode(&mut e)?;
Ok(e)
}
}
pub trait StrictDecode: Sized {
fn strict_decode<D: io::Read>(d: D) -> Result<Self, Error>;
fn strict_deserialize(data: impl AsRef<[u8]>) -> Result<Self, Error> {
Self::strict_decode(data.as_ref())
}
}
pub fn strict_serialize<T>(data: &T) -> Result<Vec<u8>, Error>
where
T: StrictEncode,
{
let mut encoder = io::Cursor::new(vec![]);
data.strict_encode(&mut encoder)?;
Ok(encoder.into_inner())
}
pub fn strict_deserialize<T>(data: &impl AsRef<[u8]>) -> Result<T, Error>
where
T: StrictDecode,
{
let mut decoder = io::Cursor::new(data);
let rv = T::strict_decode(&mut decoder)?;
let consumed = decoder.position() as usize;
if consumed == data.as_ref().len() {
Ok(rv)
} else {
Err(Error::DataNotEntirelyConsumed)?
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, Display, From, Error)]
#[display(doc_comments)]
pub enum Error {
#[from(io::Error)]
#[from(io::ErrorKind)]
Io(IoError),
#[from(std::str::Utf8Error)]
#[from(std::string::FromUtf8Error)]
Utf8Conversion,
ExceedMaxItems(usize),
#[display(
"Invalid value {0} met as an optional type byte, which must be \
equal to either 0 (no value) or 1"
)]
WrongOptionalEncoding(u8),
EnumValueOverflow(String),
EnumValueNotKnown(String, u8),
UnsupportedDataStructure(&'static str),
ValueOutOfRange(&'static str, Range<u128>, u128),
RepeatedValue(String),
#[display(
"Data were not consumed entirely during strict decoding procedure"
)]
DataNotEntirelyConsumed,
DataIntegrityError(String),
}
impl From<Error> for fmt::Error {
#[inline]
fn from(_: Error) -> Self {
fmt::Error
}
}