-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathlib.rs
More file actions
89 lines (74 loc) · 2.51 KB
/
lib.rs
File metadata and controls
89 lines (74 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#![crate_type = "lib"]
#![deny(trivial_numeric_casts, warnings)]
#![allow(broken_intra_doc_links)]
#![allow(
clippy::too_many_arguments,
clippy::implicit_hasher,
clippy::module_inception,
clippy::new_without_default
)]
// Workaround for issue: https://github.com/rust-lang/rust/issues/64450
extern crate offset_capnp_conv_derive as capnp_conv_derive;
use std::io;
use derive_more::From;
pub use capnp_conv_derive::capnp_conv;
#[derive(Debug, From)]
pub enum CapnpConvError {
CapnpError(capnp::Error),
NotInSchema(capnp::NotInSchema),
IoError(io::Error),
}
/// Convert Rust struct to Capnp.
pub trait WriteCapnp<'a> {
/// The corresponding Capnp writer type.
// type WriterType: capnp::traits::FromPointerBuilder<'a>;
type WriterType: capnp::traits::FromPointerBuilder<'a>;
/// Converts a Rust struct to corresponding Capnp struct. This should not fail.
fn write_capnp(&self, writer: &mut Self::WriterType);
}
/// Convert Capnp struct to Rust.
pub trait ReadCapnp<'a>: Sized {
/// The corresponding Capnp reader type.
type ReaderType: capnp::traits::FromPointerReader<'a>;
/// Converts a Capnp struct to corresponding Rust struct.
fn read_capnp(reader: &Self::ReaderType) -> Result<Self, CapnpConvError>;
}
pub trait ToCapnpBytes {
/// Serialize a Rust struct into bytes using Capnp
fn to_capnp_bytes(&self) -> Vec<u8>;
}
pub trait FromCapnpBytes: Sized {
/// Deserialize a Rust struct from bytes using Capnp
fn from_capnp_bytes(bytes: &[u8]) -> Result<Self, CapnpConvError>;
}
impl<T> ToCapnpBytes for T
where
T: for<'a> WriteCapnp<'a>,
{
fn to_capnp_bytes(&self) -> Vec<u8> {
let mut builder = capnp::message::Builder::new_default();
// A trick to avoid borrow checker issues:
{
let mut struct_builder = builder.init_root::<T::WriterType>();
self.write_capnp(&mut struct_builder);
}
let mut data = Vec::new();
// Should never really fail:
capnp::serialize_packed::write_message(&mut data, &builder).unwrap();
data
}
}
impl<T> FromCapnpBytes for T
where
T: for<'a> ReadCapnp<'a>,
{
fn from_capnp_bytes(bytes: &[u8]) -> Result<Self, CapnpConvError> {
let mut cursor = io::Cursor::new(&bytes);
let reader = capnp::serialize_packed::read_message(
&mut cursor,
capnp::message::ReaderOptions::new(),
)?;
let struct_reader = reader.get_root::<T::ReaderType>()?;
Ok(Self::read_capnp(&struct_reader)?)
}
}