Skip to content

Commit

Permalink
Merge pull request #10 from nicholaschiasson/minor/support-serialization
Browse files Browse the repository at this point in the history
Add support for serialization with feature flag
  • Loading branch information
nicholaschiasson committed Jul 5, 2023
2 parents acb4e3a + d222a8a commit f92b3f4
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 16 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:
- name: Checkout
uses: actions/[email protected]
- name: Check
run: cargo check --verbose
run: cargo check --all-features --verbose
- name: Format
run: cargo fmt --check --verbose
- name: Lint
run: rustup component add clippy && cargo clippy --verbose
- name: Test
run: cargo test --verbose
run: cargo test --all-features --verbose

tag:
if: github.event_name == 'push' || (github.base_ref == 'main' && github.event.pull_request.merged == true)
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
- name: Build
shell: bash
run: |
cargo build --release --verbose
cargo build --all-features --release --verbose
publish:
if: github.event_name == 'push' || (github.base_ref == 'main' && github.event.pull_request.merged == true)
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ github = { repository = "nicholaschiasson/fcidr" }
maintenance = { status = "passively-maintained" }

[dependencies]
serde = { version = "1.0", optional = true }

[dev-dependencies]
serde_json = "1.0"
8 changes: 7 additions & 1 deletion src/cidr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
str::FromStr,
};

#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Cidr {
network: Ipv4Addr,
prefix: u8,
Expand All @@ -20,6 +20,12 @@ pub enum Error {
Impossible(String),
}

impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}

impl Cidr {
pub fn new(network: Ipv4Addr, prefix: u8) -> Result<Self, Error> {
if prefix as u32 > u32::BITS {
Expand Down
15 changes: 3 additions & 12 deletions src/fcidr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, fmt::Display, rc::Rc};
use std::{cell::RefCell, rc::Rc};

use crate::{cidr, Cidr};

Expand Down Expand Up @@ -139,15 +139,6 @@ impl Fcidr {
}
}

impl Display for Fcidr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for cidr in self.into_iter() {
writeln!(f, "{cidr}")?;
}
Ok(())
}
}

impl IntoIterator for Fcidr {
type Item = Cidr;

Expand Down Expand Up @@ -226,9 +217,9 @@ mod tests {
.exclude("255.255.255.255/32".parse().unwrap())
.unwrap();
// fcidr.include("0.0.0.0/0".parse().unwrap()).unwrap();
println!("{fcidr}");
// println!("{fcidr}");
// println!("{:?}", fcidr.iter().collect::<Vec<_>>());
println!("{fcidr:?}");
// println!("{fcidr:?}");
// fcidr.exclude("10.0.0.1/32".parse().unwrap());
// for i in 0..=32 {
// println!("{} {}", i / 8, i % 8);
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod cidr;
mod fcidr;
mod serde;

pub use crate::cidr::Cidr;
pub use crate::fcidr::Fcidr;
108 changes: 108 additions & 0 deletions src/serde.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#![cfg(feature = "serde")]
#![cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]

use std::str::FromStr;

use serde::{de::Visitor, ser::SerializeSeq, Deserialize, Serialize};

use crate::{Cidr, Fcidr};

struct CidrVisitor;

impl<'de> Visitor<'de> for CidrVisitor {
type Value = Cidr;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a cidr block")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Self::Value::from_str(v).map_err(serde::de::Error::custom)
}
}

impl<'de> Deserialize<'de> for Cidr {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(CidrVisitor)
}
}

impl Serialize for Cidr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

struct FcidrVisitor;

impl<'de> Visitor<'de> for FcidrVisitor {
type Value = Fcidr;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a list of cidr blocks")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut value = Self::Value::default();
while let Some(element) = seq.next_element()? {
value.include(element).map_err(serde::de::Error::custom)?;
}
Ok(value)
}
}

impl<'de> Deserialize<'de> for Fcidr {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(FcidrVisitor)
}
}

impl Serialize for Fcidr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.iter().count()))?;
for element in self {
seq.serialize_element(&element)?;
}
seq.end()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_works() {
let cidr: Cidr = serde_json::from_str("\"127.0.1.2/31\"").unwrap();
println!("{cidr}");
println!(
"{}",
serde_json::json!("128.0.0.0/30".parse::<Cidr>().unwrap())
);
let mut fcidr = Fcidr::new("10.0.0.0/8".parse().unwrap()).unwrap();
fcidr.exclude("10.128.128.127/32".parse().unwrap()).unwrap();
println!("{}", serde_json::json!(fcidr));
let fcidr: Fcidr = serde_json::from_str("[\"10.0.0.0/9\",\"10.128.0.0/17\",\"10.128.128.0/26\",\"10.128.128.64/27\",\"10.128.128.96/28\",\"10.128.128.112/29\",\"10.128.128.120/30\",\"10.128.128.124/31\",\"10.128.128.126/32\",\"10.128.128.128/25\",\"10.128.129.0/24\",\"10.128.130.0/23\",\"10.128.132.0/22\",\"10.128.136.0/21\",\"10.128.144.0/20\",\"10.128.160.0/19\",\"10.128.192.0/18\",\"10.129.0.0/16\",\"10.130.0.0/15\",\"10.132.0.0/14\",\"10.136.0.0/13\",\"10.144.0.0/12\",\"10.160.0.0/11\",\"10.192.0.0/10\"]").unwrap();
for (i, cidr) in fcidr.iter().enumerate() {
println!("{i} - {cidr}");
}
}
}

0 comments on commit f92b3f4

Please sign in to comment.