stdcode/
lib.rs

1use std::{
2    fmt::{Debug, Display},
3    str::FromStr,
4};
5
6use bincode::Options;
7use bytes::Bytes;
8use serde::{de::DeserializeOwned, Deserialize, Serialize};
9pub mod asstr;
10pub mod hex;
11pub mod hex32;
12pub mod hexvec;
13pub mod try_asstr;
14
15/// A wrapper that serializes whatever's wrapped inside with its [Display] and [FromStr] implementations.
16#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
17#[serde(transparent)]
18pub struct SerializeAsString<T: Display + FromStr + Serialize + DeserializeOwned>(
19    #[serde(with = "crate::asstr")] pub T,
20)
21where
22    T::Err: Debug;
23
24/// Safe deserialize that prevents DoS attacks.
25pub fn deserialize<T: DeserializeOwned>(bts: &[u8]) -> bincode::Result<T> {
26    bincode::DefaultOptions::new()
27        .with_varint_encoding()
28        .reject_trailing_bytes()
29        .with_limit(bts.len() as u64)
30        .deserialize(bts)
31}
32
33/// Serialize the stuff
34pub fn serialize<T: Serialize>(v: &T) -> bincode::Result<Vec<u8>> {
35    bincode::DefaultOptions::new()
36        .with_varint_encoding()
37        .reject_trailing_bytes()
38        .serialize(v)
39}
40
41/// An extension trait for all stdcode-serializable stuff.
42pub trait StdcodeSerializeExt: Serialize + Sized {
43    fn stdcode(&self) -> Vec<u8> {
44        serialize(self).unwrap()
45    }
46}
47
48impl<T: Serialize + Sized> StdcodeSerializeExt for T {}
49
50#[derive(Serialize, Deserialize, Clone)]
51#[serde(transparent)]
52#[repr(transparent)]
53/// A bytevector that serializes as a bytevector for binary formats (like stdcode), but as hex for string formats (like JSON).
54///
55/// Does not have an ergonomic interface for using directly. Instead, use [HexBytes], which is a [serde_with] adapter.
56pub struct HexBytesInner(#[serde(with = "crate::hex")] Vec<u8>);
57
58impl<T: AsRef<[u8]>> From<T> for HexBytesInner {
59    fn from(s: T) -> Self {
60        HexBytesInner(s.as_ref().to_vec())
61    }
62}
63
64impl From<HexBytesInner> for Vec<u8> {
65    fn from(t: HexBytesInner) -> Self {
66        t.0
67    }
68}
69
70impl From<HexBytesInner> for Bytes {
71    fn from(t: HexBytesInner) -> Self {
72        t.0.into()
73    }
74}
75
76/// A type, similar to [serde_with::Bytes], except using hex encoding for text formats.
77pub type HexBytes = serde_with::FromInto<HexBytesInner>;