From 38e5657fe10ae3305f4725437b851b1cef7d2a47 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Mon, 30 Jan 2023 12:45:33 +0100 Subject: [PATCH] Implement Debug and defmt::Format for Url --- src/defmt_impl.rs | 22 ++++++++++++++++++++ src/lib.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/defmt_impl.rs diff --git a/src/defmt_impl.rs b/src/defmt_impl.rs new file mode 100644 index 0000000..e32c0e4 --- /dev/null +++ b/src/defmt_impl.rs @@ -0,0 +1,22 @@ +#[cfg(test)] +mod tests { + //! This module is required in order to satisfy the requirements of defmt, while running tests. + //! Note that this will cause all log `defmt::` log statements to be thrown away. + + #[defmt::global_logger] + struct GlobalLogger; + + unsafe impl defmt::Logger for GlobalLogger { + fn acquire() {} + unsafe fn flush() {} + unsafe fn release() {} + unsafe fn write(_bytes: &[u8]) {} + } + + defmt::timestamp!(""); + + #[defmt::panic_handler] + fn panic() -> ! { + panic!() + } +} diff --git a/src/lib.rs b/src/lib.rs index 718be04..9a95bcd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,53 @@ #![no_std] mod error; +#[cfg(feature = "defmt")] +mod defmt_impl; pub use error::Error; /// A parsed URL to extract different parts of the URL. pub struct Url<'a> { - host: &'a str, scheme: UrlScheme, + host: &'a str, port: Option, path: &'a str, } +impl core::fmt::Debug for Url<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + if let Some(port) = self.port { + write!( + f, + "{}://{}:{}{}", + self.scheme.as_str(), + self.host, + port, + self.path + ) + } else { + write!(f, "{}://{}{}", self.scheme.as_str(), self.host, self.path) + } + } +} + +#[cfg(feature = "defmt")] +impl defmt::Format for Url<'_> { + fn format(&self, fmt: defmt::Formatter) { + if let Some(port) = self.port { + defmt::write!( + fmt, + "{}://{}:{}{}", + self.scheme.as_str(), + self.host, + port, + self.path + ) + } else { + defmt::write!(fmt, "{}://{}{}", self.scheme.as_str(), self.host, self.path) + } + } +} + #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum UrlScheme { @@ -26,7 +63,7 @@ pub enum UrlScheme { impl UrlScheme { /// str representation of the scheme - /// + /// /// The returned str is always lowercase pub fn as_str(&self) -> &str { match self { @@ -126,6 +163,7 @@ impl<'a> Url<'a> { #[cfg(test)] mod tests { extern crate std; + use super::*; #[test] @@ -158,6 +196,8 @@ mod tests { assert_eq!(url.host(), "localhost"); assert_eq!(url.port_or_default(), 80); assert_eq!(url.path(), "/"); + + assert_eq!("http://localhost/", std::format!("{:?}", url)); } #[test] @@ -167,6 +207,8 @@ mod tests { assert_eq!(url.host(), "localhost"); assert_eq!(url.port_or_default(), 80); assert_eq!(url.path(), "/foo/bar"); + + assert_eq!("http://localhost/foo/bar", std::format!("{:?}", url)); } #[test] @@ -176,6 +218,8 @@ mod tests { assert_eq!(url.host(), "localhost"); assert_eq!(url.port().unwrap(), 8088); assert_eq!(url.path(), "/"); + + assert_eq!("http://localhost:8088/", std::format!("{:?}", url)); } #[test] @@ -185,6 +229,8 @@ mod tests { assert_eq!(url.host(), "localhost"); assert_eq!(url.port().unwrap(), 8088); assert_eq!(url.path(), "/foo/bar"); + + assert_eq!("http://localhost:8088/foo/bar", std::format!("{:?}", url)); } #[test] @@ -194,5 +240,7 @@ mod tests { assert_eq!(url.host(), "localhost"); assert_eq!(url.port_or_default(), 443); assert_eq!(url.path(), "/"); + + assert_eq!("https://localhost/", std::format!("{:?}", url)); } }