Skip to content

Commit 3fd8e33

Browse files
committed
serde serializer + deserializer for NvList
Add a serde serializer that can serialize structs to NvList's. Add a serde deserializer that can deserialize NvList's into structs.
1 parent 42bbed3 commit 3fd8e33

File tree

6 files changed

+925
-0
lines changed

6 files changed

+925
-0
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nvpair/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ edition = "2018"
1313
cstr-argument = "0.1"
1414
nvpair-sys = { path = "../nvpair-sys", version = "0.4.0" }
1515
foreign-types = "0.5.0"
16+
serde = "1.0"
1617

1718
[badges]
1819
travis-ci = { repository = "jmesmon/rust-libzfs" }

nvpair/src/de.rs

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
use crate::*;
2+
use ::serde::de::{DeserializeSeed, MapAccess, SeqAccess, Visitor};
3+
use ::serde::{de, forward_to_deserialize_any, Deserialize};
4+
use serde::de::DeserializeOwned;
5+
use std::ffi::CStr;
6+
use std::marker::PhantomData;
7+
8+
pub fn from_bytes<T>(buf: &[u8]) -> Result<T>
9+
where
10+
T: DeserializeOwned,
11+
{
12+
from_nvlist(&NvList::try_unpack(buf)?)
13+
}
14+
15+
pub fn from_nvlist<'a, T>(s: &'a NvList) -> Result<T>
16+
where
17+
T: Deserialize<'a>,
18+
{
19+
let mut deserializer = Deserializer::from_nvlist(s);
20+
let t = T::deserialize(&mut deserializer)?;
21+
/*
22+
match deserializer.iterator.next() {
23+
Some(pair) => Err(Error::Message(format!(
24+
"unconsumed nvpairs, including {:?}",
25+
pair
26+
))),
27+
None => Ok(t),
28+
}
29+
*/
30+
Ok(t)
31+
}
32+
33+
#[derive(Debug)]
34+
struct Deserializer<'de> {
35+
iterator: NvListIter<'de>,
36+
data: Option<NvData<'de>>,
37+
}
38+
39+
impl<'de> Deserializer<'de> {
40+
fn from_nvlist(input: &'de NvListRef) -> Self {
41+
Deserializer {
42+
iterator: input.iter(),
43+
data: None,
44+
}
45+
}
46+
}
47+
48+
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
49+
type Error = Error;
50+
51+
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
52+
where
53+
V: Visitor<'de>,
54+
{
55+
visitor.visit_map(self)
56+
}
57+
58+
forward_to_deserialize_any! {
59+
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
60+
bytes byte_buf option unit unit_struct newtype_struct seq tuple
61+
tuple_struct map struct enum identifier ignored_any
62+
}
63+
}
64+
65+
impl<'de> MapAccess<'de> for Deserializer<'de> {
66+
type Error = Error;
67+
68+
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
69+
where
70+
K: DeserializeSeed<'de>,
71+
{
72+
let nvpair = match self.iterator.next() {
73+
Some(nvpair) => nvpair,
74+
None => return Ok(None),
75+
};
76+
77+
let mut key_deserializer = KeyDeserializer { key: nvpair.name() };
78+
self.data = Some(nvpair.data());
79+
80+
seed.deserialize(&mut key_deserializer).map(Some)
81+
}
82+
83+
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
84+
where
85+
V: DeserializeSeed<'de>,
86+
{
87+
match self.data.take() {
88+
Some(data) => {
89+
let mut value_deserializer = ValueDeserializer { data };
90+
seed.deserialize(&mut value_deserializer)
91+
}
92+
None => Err(Error::Message("expected value but not present".to_string())),
93+
}
94+
}
95+
}
96+
97+
#[derive(Debug)]
98+
struct KeyDeserializer<'de> {
99+
key: &'de CStr,
100+
}
101+
102+
impl<'de, 'a> de::Deserializer<'de> for &'a mut KeyDeserializer<'de> {
103+
type Error = Error;
104+
105+
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
106+
where
107+
V: Visitor<'de>,
108+
{
109+
visitor.visit_borrowed_str(self.key.to_str()?)
110+
}
111+
112+
forward_to_deserialize_any! {
113+
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
114+
bytes byte_buf option unit unit_struct newtype_struct seq tuple
115+
tuple_struct map struct enum identifier ignored_any
116+
}
117+
}
118+
119+
#[derive(Debug)]
120+
struct ValueDeserializer<'de> {
121+
data: NvData<'de>,
122+
}
123+
124+
impl<'de, 'a> de::Deserializer<'de> for &'a mut ValueDeserializer<'de> {
125+
type Error = Error;
126+
127+
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
128+
where
129+
V: Visitor<'de>,
130+
{
131+
match self.data {
132+
NvData::Unknown => Err(Error::UnknownNvPairType),
133+
NvData::Bool => visitor.visit_none(),
134+
NvData::BoolV(v) => visitor.visit_bool(v),
135+
NvData::Byte(v) => visitor.visit_u8(v),
136+
NvData::Int8(v) => visitor.visit_i8(v),
137+
NvData::Uint8(v) => visitor.visit_u8(v),
138+
NvData::Int16(v) => visitor.visit_i16(v),
139+
NvData::Uint16(v) => visitor.visit_u16(v),
140+
NvData::Int32(v) => visitor.visit_i32(v),
141+
NvData::Uint32(v) => visitor.visit_u32(v),
142+
NvData::Int64(v) => visitor.visit_i64(v),
143+
NvData::Uint64(v) => visitor.visit_u64(v),
144+
NvData::Str(v) => visitor.visit_borrowed_str(v.to_str()?),
145+
NvData::NvListRef(v) => visitor.visit_map(Deserializer::from_nvlist(v)),
146+
NvData::ByteArray(v) => visitor.visit_borrowed_bytes(v),
147+
NvData::Int8Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
148+
NvData::Uint8Array(v) => visitor.visit_borrowed_bytes(v),
149+
NvData::Int16Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
150+
NvData::Uint16Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
151+
NvData::Int32Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
152+
NvData::Uint32Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
153+
NvData::Int64Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
154+
NvData::Uint64Array(v) => visitor.visit_seq(SeqAccessor::new(v.iter())),
155+
NvData::NvListRefArray(_) => Err(Error::UnknownNvPairType),
156+
}
157+
}
158+
159+
forward_to_deserialize_any! {
160+
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
161+
bytes byte_buf option unit unit_struct newtype_struct seq tuple
162+
tuple_struct map struct enum identifier ignored_any
163+
}
164+
}
165+
166+
#[derive(Debug)]
167+
struct SeqAccessor<'de, I>
168+
where
169+
I: Iterator,
170+
<I as Iterator>::Item: Into<NvData<'de>>,
171+
{
172+
iterator: I,
173+
_phantom: std::marker::PhantomData<&'de I>,
174+
}
175+
176+
impl<'de, I> SeqAccessor<'de, I>
177+
where
178+
I: Iterator,
179+
<I as Iterator>::Item: Into<NvData<'de>>,
180+
{
181+
fn new(iterator: I) -> Self {
182+
Self {
183+
iterator,
184+
_phantom: PhantomData,
185+
}
186+
}
187+
}
188+
189+
impl<'de, I> SeqAccess<'de> for SeqAccessor<'de, I>
190+
where
191+
I: Iterator,
192+
<I as Iterator>::Item: Into<NvData<'de>>,
193+
{
194+
type Error = Error;
195+
196+
fn next_element_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
197+
where
198+
K: DeserializeSeed<'de>,
199+
{
200+
let item = match self.iterator.next() {
201+
Some(item) => item,
202+
None => return Ok(None),
203+
};
204+
205+
let mut vd = ValueDeserializer { data: item.into() };
206+
seed.deserialize(&mut vd).map(Some)
207+
}
208+
}
209+
210+
impl From<&u64> for NvData<'_> {
211+
fn from(v: &u64) -> Self {
212+
NvData::Uint64(*v)
213+
}
214+
}
215+
216+
impl From<&i64> for NvData<'_> {
217+
fn from(v: &i64) -> Self {
218+
NvData::Int64(*v)
219+
}
220+
}
221+
222+
impl From<&u32> for NvData<'_> {
223+
fn from(v: &u32) -> Self {
224+
NvData::Uint32(*v)
225+
}
226+
}
227+
228+
impl From<&i32> for NvData<'_> {
229+
fn from(v: &i32) -> Self {
230+
NvData::Int32(*v)
231+
}
232+
}
233+
234+
impl From<&u16> for NvData<'_> {
235+
fn from(v: &u16) -> Self {
236+
NvData::Uint16(*v)
237+
}
238+
}
239+
240+
impl From<&i16> for NvData<'_> {
241+
fn from(v: &i16) -> Self {
242+
NvData::Int16(*v)
243+
}
244+
}
245+
246+
impl From<&u8> for NvData<'_> {
247+
fn from(v: &u8) -> Self {
248+
NvData::Uint8(*v)
249+
}
250+
}
251+
252+
impl From<&i8> for NvData<'_> {
253+
fn from(v: &i8) -> Self {
254+
NvData::Int8(*v)
255+
}
256+
}
257+
258+
/*
259+
impl<'a> From<&'a NvListRef> for NvData<'a> {
260+
fn from(v: &'a NvListRef) -> Self {
261+
NvData::NvListRef(v)
262+
}
263+
}
264+
265+
impl<'a> From<&&'a NvListRef> for NvData<'a> {
266+
fn from(v: &&'a NvListRef) -> Self {
267+
NvData::NvListRef(*v)
268+
}
269+
}
270+
*/

nvpair/src/error.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use ::serde::{de, ser};
2+
use std::ffi::NulError;
3+
use std::fmt;
4+
use std::fmt::Display;
5+
6+
pub type Result<T> = std::result::Result<T, Error>;
7+
8+
#[derive(Debug)]
9+
pub enum Error {
10+
Message(String),
11+
UnknownNvPairType,
12+
13+
// Zero or more variants that can be created directly by the Serializer and
14+
// Deserializer without going through `ser::Error` and `de::Error`. These
15+
// are specific to the format, in this case JSON.
16+
//Eof,
17+
NulError(NulError),
18+
IoError(std::io::Error),
19+
Utf8Error(std::str::Utf8Error),
20+
/*
21+
Syntax,
22+
ExpectedBoolean,
23+
ExpectedInteger,
24+
ExpectedString,
25+
ExpectedNull,
26+
ExpectedArray,
27+
ExpectedArrayComma,
28+
ExpectedArrayEnd,
29+
ExpectedMap,
30+
ExpectedMapColon,
31+
ExpectedMapComma,
32+
ExpectedMapEnd,
33+
ExpectedEnum,
34+
TrailingCharacters,
35+
*/
36+
}
37+
38+
impl ser::Error for Error {
39+
fn custom<T: Display>(msg: T) -> Self {
40+
Error::Message(msg.to_string())
41+
}
42+
}
43+
44+
impl de::Error for Error {
45+
fn custom<T: Display>(msg: T) -> Self {
46+
Error::Message(msg.to_string())
47+
}
48+
}
49+
50+
impl Display for Error {
51+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
52+
fmt::Debug::fmt(self, formatter)
53+
}
54+
}
55+
56+
impl From<NulError> for Error {
57+
fn from(e: NulError) -> Self {
58+
Error::NulError(e)
59+
}
60+
}
61+
62+
impl From<std::io::Error> for Error {
63+
fn from(e: std::io::Error) -> Self {
64+
Error::IoError(e)
65+
}
66+
}
67+
68+
impl From<std::str::Utf8Error> for Error {
69+
fn from(e: std::str::Utf8Error) -> Self {
70+
Error::Utf8Error(e)
71+
}
72+
}
73+
74+
impl std::error::Error for Error {}

0 commit comments

Comments
 (0)