mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-23 03:59:31 +00:00
fixed-bytes: add serde
, document feature flags (#226)
Some checks are pending
Audit / audit (push) Waiting to run
CI / fmt (push) Waiting to run
CI / typo (push) Waiting to run
CI / ci (macos-latest, stable, bash) (push) Waiting to run
CI / ci (ubuntu-latest, stable, bash) (push) Waiting to run
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Waiting to run
Deny / audit (push) Waiting to run
Doc / build (push) Waiting to run
Doc / deploy (push) Blocked by required conditions
Some checks are pending
Audit / audit (push) Waiting to run
CI / fmt (push) Waiting to run
CI / typo (push) Waiting to run
CI / ci (macos-latest, stable, bash) (push) Waiting to run
CI / ci (ubuntu-latest, stable, bash) (push) Waiting to run
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Waiting to run
Deny / audit (push) Waiting to run
Doc / build (push) Waiting to run
Doc / deploy (push) Blocked by required conditions
* fixed-bytes: add `serde`, document feature flags * manual impl `serde::Deserialize` * add serde tests
This commit is contained in:
parent
5aeb8af4b4
commit
824651c8cf
4 changed files with 116 additions and 2 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -274,6 +274,9 @@ name = "bytes"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
|
@ -641,6 +644,8 @@ name = "cuprate-fixed-bytes"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,14 @@ license = "MIT"
|
||||||
authors = ["Boog900"]
|
authors = ["Boog900"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std", "serde"]
|
||||||
std = ["bytes/std", "dep:thiserror"]
|
std = ["bytes/std", "dep:thiserror"]
|
||||||
|
serde = ["bytes/serde", "dep:serde"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = { workspace = true, optional = true }
|
thiserror = { workspace = true, optional = true }
|
||||||
bytes = { workspace = true }
|
bytes = { workspace = true }
|
||||||
|
serde = { workspace = true, features = ["derive"], optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_json = { workspace = true, features = ["std"] }
|
10
net/fixed-bytes/README.md
Normal file
10
net/fixed-bytes/README.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# `cuprate-fixed-bytes`
|
||||||
|
TODO
|
||||||
|
|
||||||
|
# Feature flags
|
||||||
|
| Feature flag | Does what |
|
||||||
|
|--------------|-----------|
|
||||||
|
| `std` | TODO
|
||||||
|
| `serde` | Enables `serde` on applicable types
|
||||||
|
|
||||||
|
`serde` is enabled by default.
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{Debug, Formatter},
|
fmt::{Debug, Formatter},
|
||||||
ops::{Deref, Index},
|
ops::{Deref, Index},
|
||||||
|
@ -5,7 +7,11 @@ use core::{
|
||||||
|
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
#[cfg_attr(feature = "std", derive(thiserror::Error))]
|
#[cfg_attr(feature = "std", derive(thiserror::Error))]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||||
pub enum FixedByteError {
|
pub enum FixedByteError {
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "std",
|
feature = "std",
|
||||||
|
@ -43,8 +49,30 @@ impl Debug for FixedByteError {
|
||||||
/// Internally this is just a wrapper around [`Bytes`], with the constructors checking that the length is equal to `N`.
|
/// Internally this is just a wrapper around [`Bytes`], with the constructors checking that the length is equal to `N`.
|
||||||
/// This implements [`Deref`] with the target being `[u8; N]`.
|
/// This implements [`Deref`] with the target being `[u8; N]`.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct ByteArray<const N: usize>(Bytes);
|
pub struct ByteArray<const N: usize>(Bytes);
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<'de, const N: usize> Deserialize<'de> for ByteArray<N> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let bytes = Bytes::deserialize(deserializer)?;
|
||||||
|
let len = bytes.len();
|
||||||
|
if len == N {
|
||||||
|
Ok(Self(bytes))
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::invalid_length(
|
||||||
|
len,
|
||||||
|
&N.to_string().as_str(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> ByteArray<N> {
|
impl<const N: usize> ByteArray<N> {
|
||||||
pub fn take_bytes(self) -> Bytes {
|
pub fn take_bytes(self) -> Bytes {
|
||||||
self.0
|
self.0
|
||||||
|
@ -88,8 +116,30 @@ impl<const N: usize> TryFrom<Vec<u8>> for ByteArray<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||||
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct ByteArrayVec<const N: usize>(Bytes);
|
pub struct ByteArrayVec<const N: usize>(Bytes);
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
impl<'de, const N: usize> Deserialize<'de> for ByteArrayVec<N> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let bytes = Bytes::deserialize(deserializer)?;
|
||||||
|
let len = bytes.len();
|
||||||
|
if len % N == 0 {
|
||||||
|
Ok(Self(bytes))
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::invalid_length(
|
||||||
|
len,
|
||||||
|
&N.to_string().as_str(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> ByteArrayVec<N> {
|
impl<const N: usize> ByteArrayVec<N> {
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.0.len() / N
|
self.0.len() / N
|
||||||
|
@ -197,6 +247,8 @@ impl<const N: usize> Index<usize> for ByteArrayVec<N> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use serde_json::{from_str, to_string};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -207,4 +259,46 @@ mod tests {
|
||||||
assert_eq!(bytes.len(), 100);
|
assert_eq!(bytes.len(), 100);
|
||||||
let _ = bytes[99];
|
let _ = bytes[99];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests that `serde` works on [`ByteArray`].
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
fn byte_array_serde() {
|
||||||
|
let b = ByteArray::from([1, 0, 0, 0, 1]);
|
||||||
|
let string = to_string(&b).unwrap();
|
||||||
|
assert_eq!(string, "[1,0,0,0,1]");
|
||||||
|
let b2 = from_str::<ByteArray<5>>(&string).unwrap();
|
||||||
|
assert_eq!(b, b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tests that `serde` works on [`ByteArrayVec`].
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
fn byte_array_vec_serde() {
|
||||||
|
let b = ByteArrayVec::from([1, 0, 0, 0, 1]);
|
||||||
|
let string = to_string(&b).unwrap();
|
||||||
|
assert_eq!(string, "[1,0,0,0,1]");
|
||||||
|
let b2 = from_str::<ByteArrayVec<5>>(&string).unwrap();
|
||||||
|
assert_eq!(b, b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tests that bad input `serde` fails on [`ByteArray`].
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
#[should_panic(
|
||||||
|
expected = r#"called `Result::unwrap()` on an `Err` value: Error("invalid length 4, expected 5", line: 0, column: 0)"#
|
||||||
|
)]
|
||||||
|
fn byte_array_bad_deserialize() {
|
||||||
|
from_str::<ByteArray<5>>("[1,0,0,0]").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tests that bad input `serde` fails on [`ByteArrayVec`].
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
#[should_panic(
|
||||||
|
expected = r#"called `Result::unwrap()` on an `Err` value: Error("invalid length 4, expected 5", line: 0, column: 0)"#
|
||||||
|
)]
|
||||||
|
fn byte_array_vec_bad_deserialize() {
|
||||||
|
from_str::<ByteArrayVec<5>>("[1,0,0,0]").unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue