-
-
Notifications
You must be signed in to change notification settings - Fork 148
feat(env_filter): support no_std #404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,6 @@ keywords = ["logging", "log", "logger"] | |
| repository.workspace = true | ||
| license.workspace = true | ||
| edition.workspace = true | ||
| rust-version.workspace = true | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this now have no MSRV? |
||
| include.workspace = true | ||
|
|
||
| [package.metadata.docs.rs] | ||
|
|
@@ -26,12 +25,13 @@ pre-release-replacements = [ | |
| ] | ||
|
|
||
| [features] | ||
| default = ["regex"] | ||
| default = ["std", "regex"] | ||
| regex = ["dep:regex"] | ||
| std = ["regex/std"] | ||
|
|
||
| [dependencies] | ||
| log = { version = "0.4.29", features = ["std"] } | ||
| regex = { version = "1.12.3", optional = true, default-features=false, features=["std", "perf"] } | ||
| log = { version = "0.4.29", default-features = false } | ||
| regex = { version = "1.12.3", optional = true, default-features=false, features=["perf"] } | ||
|
|
||
| [dev-dependencies] | ||
| snapbox = "1.0" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| use alloc::string::String; | ||
|
|
||
| use log::Level; | ||
| use log::LevelFilter; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| use std::env; | ||
| use std::fmt; | ||
| use std::mem; | ||
| use alloc::{borrow::ToOwned, string::ToString, vec::Vec}; | ||
| use core::{fmt, mem}; | ||
|
|
||
| use log::{LevelFilter, Metadata, Record}; | ||
|
|
||
|
|
@@ -48,10 +47,11 @@ impl Builder { | |
| } | ||
|
|
||
| /// Initializes the filter builder from an environment. | ||
| #[cfg(feature = "std")] | ||
| pub fn from_env(env: &str) -> Builder { | ||
| let mut builder = Builder::new(); | ||
|
|
||
| if let Ok(s) = env::var(env) { | ||
| if let Ok(s) = std::env::var(env) { | ||
| builder.parse(&s); | ||
| } | ||
|
|
||
|
|
@@ -108,7 +108,10 @@ impl Builder { | |
| } = parse_spec(filters); | ||
|
|
||
| for error in errors { | ||
| #[cfg(feature = "std")] | ||
| eprintln!("warning: {error}, ignoring it"); | ||
| #[cfg(not(feature = "std"))] | ||
| log::warn!("{error}, ignoring it"); | ||
|
Comment on lines
+113
to
+114
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for creating the logger in the first place, so I don't think it is too meaningful to log at this point. |
||
| } | ||
|
|
||
| self.filter = filter; | ||
|
|
@@ -258,8 +261,9 @@ impl fmt::Debug for Filter { | |
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use alloc::{borrow::ToOwned, vec, vec::Vec}; | ||
|
|
||
| use log::{Level, LevelFilter}; | ||
| use snapbox::{assert_data_eq, str}; | ||
|
|
||
| use super::{enabled, Builder, Directive, Filter}; | ||
|
|
||
|
|
@@ -486,10 +490,12 @@ mod tests { | |
|
|
||
| #[test] | ||
| fn try_parse_invalid_filter() { | ||
| #[allow(unused_variables)] | ||
| let error = Builder::new().try_parse("info,crate1=invalid").unwrap_err(); | ||
| assert_data_eq!( | ||
| #[cfg(feature = "std")] | ||
| snapbox::assert_data_eq!( | ||
| error, | ||
| str!["error parsing logger filter: invalid logging spec 'invalid'"] | ||
| snapbox::str!["error parsing logger filter: invalid logging spec 'invalid'"] | ||
| ); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,9 +38,14 @@ | |
| //! ``` | ||
|
|
||
| #![cfg_attr(docsrs, feature(doc_cfg))] | ||
| #![cfg_attr(not(feature = "std"), no_std)] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my packages I tend to do #![cfg_attr(all(not(feature = "std"), not(test)), no_std)]to avoid needing to do weird stuff in the tests |
||
| #![warn(missing_docs)] | ||
| #![warn(clippy::print_stderr)] | ||
| #![warn(clippy::print_stdout)] | ||
|
cagatay-y marked this conversation as resolved.
|
||
| #![warn(clippy::std_instead_of_core)] | ||
| #![warn(clippy::std_instead_of_alloc)] | ||
|
|
||
| extern crate alloc; | ||
|
|
||
| mod directive; | ||
| mod filter; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| use alloc::{borrow::ToOwned, format, string::String, vec::Vec}; | ||
| use core::fmt::{Display, Formatter}; | ||
|
|
||
| use log::LevelFilter; | ||
| use std::error::Error; | ||
| use std::fmt::{Display, Formatter}; | ||
|
|
||
| use crate::Directive; | ||
| use crate::FilterOp; | ||
|
|
@@ -46,12 +47,17 @@ pub struct ParseError { | |
| } | ||
|
|
||
| impl Display for ParseError { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { | ||
| write!(f, "error parsing logger filter: {}", self.details) | ||
| } | ||
| } | ||
|
|
||
| impl Error for ParseError {} | ||
| #[cfg(feature = "std")] | ||
| #[allow(clippy::std_instead_of_core)] | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allow stopped working starting from Rust 1.91. I could not find anything in the release notes that would affect it. |
||
| impl std::error::Error for ParseError {} | ||
|
|
||
| #[cfg(not(feature = "std"))] | ||
| impl core::error::Error for ParseError {} | ||
|
|
||
| /// Parse a logging specification string (e.g: `crate1,crate2::mod3,crate3::x=error/foo`) | ||
| /// and return a vector with log directives. | ||
|
|
@@ -115,9 +121,13 @@ pub(crate) fn parse_spec(spec: &str) -> ParseResult { | |
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use alloc::{borrow::ToOwned, string::ToString}; | ||
|
|
||
| use crate::ParseError; | ||
| use log::LevelFilter; | ||
| use snapbox::{assert_data_eq, str, Data, IntoData}; | ||
| #[cfg(feature = "std")] | ||
| use snapbox::{assert_data_eq, str}; | ||
| use snapbox::{Data, IntoData}; | ||
|
|
||
| use super::{parse_spec, ParseResult}; | ||
|
|
||
|
|
@@ -164,6 +174,7 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 1); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'crate1::mod1=warn=info'"] | ||
|
|
@@ -185,6 +196,7 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 1); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!(&errors[0], str!["invalid logging spec 'noNumber'"]); | ||
| } | ||
|
|
||
|
|
@@ -203,6 +215,7 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 1); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!(&errors[0], str!["invalid logging spec 'wrong'"]); | ||
| } | ||
|
|
||
|
|
@@ -221,6 +234,7 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 1); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!(&errors[0], str!["invalid logging spec 'wrong'"]); | ||
| } | ||
|
|
||
|
|
@@ -394,6 +408,7 @@ mod tests { | |
| assert!(filter.is_some() && filter.unwrap().to_string() == "a.c"); | ||
|
|
||
| assert_eq!(errors.len(), 1); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'crate1::mod1=error=warn'"] | ||
|
|
@@ -425,6 +440,7 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 1); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'debug/abc/a.c' (too many '/'s)"] | ||
|
|
@@ -446,14 +462,17 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 2); | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'crate1::mod1=warn=info'"] | ||
| ); | ||
| assert_data_eq!( | ||
| &errors[1], | ||
| str!["invalid logging spec 'crate3=error=error'"] | ||
| ); | ||
| #[cfg(feature = "std")] | ||
| { | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'crate1::mod1=warn=info'"] | ||
| ); | ||
| assert_data_eq!( | ||
| &errors[1], | ||
| str!["invalid logging spec 'crate3=error=error'"] | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
|
|
@@ -471,8 +490,11 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 2); | ||
| assert_data_eq!(&errors[0], str!["invalid logging spec 'noNumber'"]); | ||
| assert_data_eq!(&errors[1], str!["invalid logging spec 'invalid'"]); | ||
| #[cfg(feature = "std")] | ||
| { | ||
| assert_data_eq!(&errors[0], str!["invalid logging spec 'noNumber'"]); | ||
| assert_data_eq!(&errors[1], str!["invalid logging spec 'invalid'"]); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
|
|
@@ -490,18 +512,23 @@ mod tests { | |
| assert!(filter.is_none()); | ||
|
|
||
| assert_eq!(errors.len(), 2); | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'crate1::mod1=debug=info'"] | ||
| ); | ||
| assert_data_eq!(&errors[1], str!["invalid logging spec 'invalid'"]); | ||
| #[cfg(feature = "std")] | ||
| { | ||
| assert_data_eq!( | ||
| &errors[0], | ||
| str!["invalid logging spec 'crate1::mod1=debug=info'"] | ||
| ); | ||
| assert_data_eq!(&errors[1], str!["invalid logging spec 'invalid'"]); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn parse_error_message_single_error() { | ||
| #[allow(unused_variables)] | ||
| let error = parse_spec("crate1::mod1=debug=info,crate2=debug") | ||
| .ok() | ||
| .unwrap_err(); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!( | ||
| error, | ||
| str!["error parsing logger filter: invalid logging spec 'crate1::mod1=debug=info'"] | ||
|
|
@@ -510,9 +537,11 @@ mod tests { | |
|
|
||
| #[test] | ||
| fn parse_error_message_multiple_errors() { | ||
| #[allow(unused_variables)] | ||
| let error = parse_spec("crate1::mod1=debug=info,crate2=debug,crate3=invalid") | ||
| .ok() | ||
| .unwrap_err(); | ||
| #[cfg(feature = "std")] | ||
| assert_data_eq!( | ||
| error, | ||
| str!["error parsing logger filter: invalid logging spec 'crate1::mod1=debug=info'"] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?