Open dzmitry-lahoda opened 8 months ago
@jdonszelmann would PR with borsh
serde considered for review and merge if made? behind borsh
feature gate
I like the idea, but why do we need borsh? I think if you implement the Serialize
and Deserialize
traits that should be enough. Then you can choose any format (like postcard or even json if you really wanted)
I talked to @NULLx76 about this and we'd prefer serde to borsh
Additionally I'm against this because Borsh seems related to blockchain/web3 which is not something we'd like to condone
Feel free to file a PR though
please reopen when change reasoning.
here is wrapper for Const if somebody needs that
//! This module provides serialization and deserialization for the `ringbuffer` crate.
use borsh::{BorshDeserialize, BorshSerialize};
use ringbuffer::{ConstGenericRingBuffer, RingBuffer};
#[derive(Debug, Default, BorshSerialize, BorshDeserialize, Clone)]
pub struct ConstGenericRingBufferWrapper<T, const CAP: usize> {
#[borsh(
serialize_with = "serialize_const_generic_ring_buffer",
deserialize_with = "deserialize_const_generic_ring_buffer"
)]
buffer: ConstGenericRingBuffer<T, CAP>,
}
/// Ring buffer is just fixed size array
#[cfg(test)]
impl<T: borsh::BorshSchema, const CAP: usize> borsh::BorshSchema
for ConstGenericRingBufferWrapper<T, CAP>
{
fn add_definitions_recursively(
definitions: &mut std::collections::BTreeMap<
borsh::schema::Declaration,
borsh::schema::Definition,
>,
) {
<[T; CAP]>::add_definitions_recursively(definitions)
}
fn declaration() -> borsh::schema::Declaration {
<[T; CAP]>::declaration()
}
}
impl<T, const CAP: usize> ConstGenericRingBufferWrapper<T, CAP> {
pub fn peek(&self) -> Option<&T> {
self.buffer.peek()
}
pub fn push(&mut self, item: T) {
self.buffer.push(item);
}
pub fn back(&self) -> Option<&T> {
self.buffer.back()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.buffer.iter()
}
pub fn get(&self, index: usize) -> Option<&T> {
self.buffer.get(index)
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn front(&self) -> Option<&T> {
self.buffer.front()
}
}
pub fn serialize_const_generic_ring_buffer<T: borsh::BorshSerialize, const CAP: usize>(
obj: &ConstGenericRingBuffer<T, CAP>,
writer: &mut impl std::io::prelude::Write,
) -> std::io::Result<()> {
for item in obj.into_iter() {
item.serialize(writer)?;
}
Ok(())
}
pub fn deserialize_const_generic_ring_buffer<T: borsh::BorshDeserialize, const CAP: usize>(
reader: &mut impl std::io::prelude::Read,
) -> std::io::Result<ConstGenericRingBuffer<T, CAP>> {
let mut buffer = ConstGenericRingBuffer::new();
for _ in 0..CAP {
buffer.push(T::try_from_reader(reader)?);
}
if T::try_from_reader(reader).is_ok() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Buffer is longs than CAP",
));
}
Ok(buffer)
}
sorry, some mix of things. closed for borsh. for serde open sure :) sorry for confusion.
All the different ringbuffers should implement Serialize and Deserialize when the
serde
feature is enabled, and should do so safely and soundly.