mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-08 10:35:32 -05:00
ip4: add custom wrapper type around IPv4 addresses for serde
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kbinxml"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
authors = ["Matt Bilker <me@mbilker.us>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -11,10 +11,11 @@ extern crate quick_xml;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Error as IoError, ErrorKind as IoErrorKind, Read, Write, stdout};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::str;
|
||||
|
||||
use failure::Fail;
|
||||
use kbinxml::{KbinXml, Options, from_bytes, to_bytes};
|
||||
use kbinxml::{Ip4Addr, KbinXml, Options, from_bytes, to_bytes};
|
||||
use minidom::Element;
|
||||
use quick_xml::Writer;
|
||||
|
||||
@@ -24,6 +25,9 @@ pub struct Testing2 {
|
||||
hi: u16,
|
||||
ho: i16,
|
||||
vu: Vec<u8>,
|
||||
opt: Option<u8>,
|
||||
opt2: Option<u8>,
|
||||
ip: Ip4Addr,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
@@ -154,6 +158,9 @@ fn main() -> std::io::Result<()> {
|
||||
hi: 32423,
|
||||
ho: 32000,
|
||||
vu: vec![33, 255, 254],
|
||||
opt: None,
|
||||
opt2: Some(111),
|
||||
ip: Ip4Addr::new(Ipv4Addr::new(127, 0, 0, 1)),
|
||||
},
|
||||
};
|
||||
let bytes = to_bytes(&obj).unwrap();
|
||||
|
||||
87
src/ip4.rs
Normal file
87
src/ip4.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use std::fmt;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
|
||||
use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
|
||||
|
||||
pub struct Ip4Addr(Ipv4Addr);
|
||||
|
||||
struct Ip4Visitor;
|
||||
|
||||
impl Ip4Addr {
|
||||
pub fn new(addr: Ipv4Addr) -> Self {
|
||||
Ip4Addr(addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Ip4Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Ip4Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Ip4Addr {
|
||||
type Target = Ipv4Addr;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Ip4Addr {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for Ip4Visitor {
|
||||
type Value = [u8; 4];
|
||||
|
||||
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("a sequence of 4 bytes with no size indicator")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where A: SeqAccess<'de>
|
||||
{
|
||||
trace!("Ip4Addr::visit_seq()");
|
||||
let v1: u8 = seq.next_element()?.unwrap();
|
||||
let v2: u8 = seq.next_element()?.unwrap();
|
||||
let v3: u8 = seq.next_element()?.unwrap();
|
||||
let v4: u8 = seq.next_element()?.unwrap();
|
||||
trace!("Ip4Addr:visit_seq() => [{}, {}, {}, {}]", v1, v2, v3, v4);
|
||||
Ok([v1, v2, v3, v4])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Ip4Addr {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
deserializer.deserialize_tuple_struct("ip4", 4, Ip4Visitor)
|
||||
.map(|v| {
|
||||
Ip4Addr(Ipv4Addr::from(v))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Ip4Addr {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer
|
||||
{
|
||||
let octets = self.0.octets();
|
||||
let mut ts = serializer.serialize_tuple_struct("ip4", 4)?;
|
||||
ts.serialize_field(&octets[0])?;
|
||||
ts.serialize_field(&octets[1])?;
|
||||
ts.serialize_field(&octets[2])?;
|
||||
ts.serialize_field(&octets[3])?;
|
||||
ts.end()
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ mod byte_buffer;
|
||||
mod compression;
|
||||
mod encoding_type;
|
||||
mod error;
|
||||
mod ip4;
|
||||
mod node_types;
|
||||
mod options;
|
||||
mod sixbit;
|
||||
@@ -43,6 +44,7 @@ pub use encoding_type::EncodingType;
|
||||
pub use error::{KbinError, KbinErrorKind, Result};
|
||||
pub use options::Options;
|
||||
pub use de::from_bytes;
|
||||
pub use ip4::Ip4Addr;
|
||||
pub use ser::to_bytes;
|
||||
|
||||
const SIGNATURE: u8 = 0xA0;
|
||||
|
||||
Reference in New Issue
Block a user