Skip to content

Commit

Permalink
Implement Deserialize trait for ServerAddress
Browse files Browse the repository at this point in the history
See: #717

Impement the serde deserializer for the ServerAddress(Url) struct
based on the existing implementation of `from_str`.
  • Loading branch information
nepalez committed Jul 18, 2023
1 parent 1c2a467 commit 7684ce5
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions nats/src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@

use lazy_static::__Deref;
use parking_lot::{Mutex, MutexGuard};
use serde::de::{self, Visitor};
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fmt::{self, Formatter};
use std::io::prelude::*;
use std::io::{self, BufReader, Error, ErrorKind};
use std::net::{Shutdown, SocketAddr, TcpStream, ToSocketAddrs};
Expand Down Expand Up @@ -748,6 +751,26 @@ impl IntoServerList for io::Result<Vec<ServerAddress>> {
}
}

struct ServerAddressVisitor;

impl<'de> Visitor<'de> for ServerAddressVisitor {
type Value = ServerAddress;

fn expecting<'a>(&self, formatter: &mut Formatter<'a>) -> fmt::Result {
formatter.write_str("a valid URL")
}

fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
ServerAddress::from_str(value).map_err(|err| E::custom(format!("{}", err)))
}
}

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

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -789,4 +812,24 @@ mod tests {
matches!(address.auth(), AuthStyle::UserPass(username, password) if &username == "myuser" && &password == "mypass")
);
}

#[test]
fn deserialize_valid_server_address() {
let serialized = "\"nats://myuser:mypass@localhost:4222\"";
let address = ServerAddress::from_str("nats://myuser:mypass@localhost:4222").unwrap();

assert_eq!(
serde_json::from_str::<ServerAddress>(serialized).unwrap(),
address
);
}

#[test]
fn deserialize_invalid_server_address() {
let serialized = "\"this is not the address\"";
let result = serde_json::from_str::<ServerAddress>(serialized);

assert!(result.is_err());
assert!(format!("{}", result.unwrap_err()).contains("NATS server URL is invalid"));
}
}

0 comments on commit 7684ce5

Please sign in to comment.