diff --git a/Cargo.toml b/Cargo.toml index 6a11287..a45eb11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,21 +24,23 @@ include = [ ] [features] +default = [] +std = ["regex?/std", "unicode-normalization?/std"] # Includes the full canonical text of each license text = [] # Allows analysis of text to determine if it might be an SPDX license text -detection = ["regex", "unicode-normalization"] +detection = ["std", "regex", "unicode-normalization"] # Allows de/serialization of a spdx::detection::Store for quicker loading -detection-cache = ["detection", "zstd"] +detection-cache = ["std", "detection", "zstd"] # Inlines a cache into this crate, which contains all of the licenses from the # SPDX crate that the crate version was packaged with -detection-inline-cache = ["detection-cache"] +detection-inline-cache = ["std", "detection-cache"] # Performs license detection in parallel within the same text -detection-parallel = ["detection", "rayon"] +detection-parallel = ["std", "detection", "rayon"] [dependencies] rayon = { version = "1.11", optional = true } -regex = { version = "1.12", optional = true } +regex = { version = "1.12", optional = true, default-features = false, features = ["perf", "unicode"] } # In most cases expressions are quite small so we can avoid heap allocations smallvec = "1.15" unicode-normalization = { version = "0.1", optional = true } diff --git a/src/error.rs b/src/error.rs index acfb77c..2be80e8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ -use std::{error::Error, fmt}; +use alloc::string::String; +use core::{error::Error, fmt}; /// An error related to parsing of an SPDX license expression /// or identifier @@ -8,7 +9,7 @@ pub struct ParseError { pub original: String, /// The range of characters in the original string that result /// in this error - pub span: std::ops::Range, + pub span: core::ops::Range, /// The specific reason for the error pub reason: Reason, } diff --git a/src/expression.rs b/src/expression.rs index 8dfd267..492fbac 100644 --- a/src/expression.rs +++ b/src/expression.rs @@ -4,9 +4,10 @@ mod minimize; mod parser; use crate::{LicenseReq, error::ParseError}; +use alloc::{string::String, vec::Vec}; +use core::fmt; pub use minimize::MinimizeError; use smallvec::SmallVec; -use std::fmt; /// A license requirement inside an SPDX license expression /// @@ -16,7 +17,7 @@ pub struct ExpressionReq { /// The license requirement pub req: LicenseReq, /// The span in the original license expression string containing the requirement - pub span: std::ops::Range, + pub span: core::ops::Range, } impl PartialEq for ExpressionReq { @@ -238,7 +239,7 @@ impl fmt::Display for Expression { } } -impl std::str::FromStr for Expression { +impl core::str::FromStr for Expression { type Err = ParseError; fn from_str(s: &str) -> Result { Self::parse(s) diff --git a/src/expression/minimize.rs b/src/expression/minimize.rs index 8e53652..78e6a9d 100644 --- a/src/expression/minimize.rs +++ b/src/expression/minimize.rs @@ -1,6 +1,7 @@ use super::Expression; use crate::{LicenseReq, Licensee}; -use std::fmt; +use alloc::vec::Vec; +use core::fmt; /// Errors that can occur when trying to minimize the requirements for an [`Expression`] #[derive(Debug, PartialEq, Eq)] @@ -25,7 +26,7 @@ impl fmt::Display for MinimizeError { } } -impl std::error::Error for MinimizeError { +impl core::error::Error for MinimizeError { fn description(&self) -> &str { match self { Self::TooManyRequirements(_) => "too many requirements in license expression", diff --git a/src/expression/parser.rs b/src/expression/parser.rs index b4385f3..3a15d9c 100644 --- a/src/expression/parser.rs +++ b/src/expression/parser.rs @@ -4,6 +4,7 @@ use crate::{ expression::{ExprNode, Expression, ExpressionReq, Operator}, lexer::{Lexer, Token}, }; +use alloc::{borrow::ToOwned, boxed::Box, string::String}; use smallvec::SmallVec; impl Expression { @@ -147,6 +148,8 @@ impl Expression { /// ).unwrap(); /// ``` pub fn parse_mode(original: &str, mode: ParseMode) -> Result { + use core::ops::Range; + // Operator precedence in SPDX 2.1 // + // WITH @@ -163,7 +166,7 @@ impl Expression { struct OpAndSpan { op: Op, - span: std::ops::Range, + span: Range, } let lexer = Lexer::new_mode(original, mode); @@ -184,7 +187,7 @@ impl Expression { Ok(()) }; - let make_err_for_token = |last_token: Option>, span: std::ops::Range| { + let make_err_for_token = |last_token: Option>, span: Range| { let expected: &[&str] = match last_token { None | Some(Token::And | Token::Or | Token::OpenParen) => &["", "("], Some(Token::CloseParen) => &["AND", "OR"], diff --git a/src/lexer.rs b/src/lexer.rs index fd45cde..d43bc29 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -2,6 +2,8 @@ use crate::{ ExceptionId, LicenseId, error::{ParseError, Reason}, }; +use alloc::borrow::ToOwned; +use core::fmt; /// Parsing configuration for SPDX expression #[derive(Default, Copy, Clone)] @@ -106,9 +108,9 @@ pub enum Token<'a> { Or, } -impl std::fmt::Display for Token<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Debug::fmt(self, f) +impl fmt::Display for Token<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self, f) } } @@ -244,7 +246,7 @@ pub struct LexerToken<'a> { /// The token that was lexed pub token: Token<'a>, /// The range of the token characters in the original license expression - pub span: std::ops::Range, + pub span: core::ops::Range, } impl<'a> Iterator for Lexer<'a> { diff --git a/src/lib.rs b/src/lib.rs index f0e56b4..d6b6a41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,9 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(missing_docs)] #![doc = include_str!("../README.md")] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; /// Error types pub mod error; @@ -21,14 +24,15 @@ pub mod detection; #[allow(missing_docs)] pub mod text; +use alloc::{boxed::Box, string::String}; +use core::{ + cmp::{self, Ordering}, + fmt, +}; pub use error::ParseError; pub use expression::Expression; pub use lexer::ParseMode; pub use licensee::Licensee; -use std::{ - cmp::{self, Ordering}, - fmt, -}; /// Flags that can apply to licenses and/or license exceptions pub mod flags { @@ -99,7 +103,7 @@ impl PartialOrd for LicenseId { } } -impl std::ops::Deref for LicenseId { +impl core::ops::Deref for LicenseId { type Target = License; #[inline] @@ -253,7 +257,7 @@ impl PartialOrd for ExceptionId { } } -impl std::ops::Deref for ExceptionId { +impl core::ops::Deref for ExceptionId { type Target = Exception; #[inline] @@ -411,8 +415,8 @@ impl Ord for LicenseItem { } } +#[allow(clippy::non_canonical_partial_ord_impl)] impl PartialOrd for LicenseItem { - #[allow(clippy::non_canonical_partial_ord_impl)] fn partial_cmp(&self, o: &Self) -> Option { match (self, o) { (Self::Spdx { id: a, .. }, Self::Spdx { id: b, .. }) => a.partial_cmp(b), @@ -514,8 +518,8 @@ impl Ord for AdditionItem { } } +#[allow(clippy::non_canonical_partial_ord_impl)] impl PartialOrd for AdditionItem { - #[allow(clippy::non_canonical_partial_ord_impl)] fn partial_cmp(&self, o: &Self) -> Option { match (self, o) { (Self::Spdx(a), Self::Spdx(b)) => a.partial_cmp(b), @@ -585,7 +589,7 @@ pub fn gnu_license_id(base: &str, or_later: bool) -> Option { v[base.len()..].copy_from_slice(b"-only"); } - let Ok(s) = std::str::from_utf8(v.as_slice()) else { + let Ok(s) = core::str::from_utf8(v.as_slice()) else { // Unreachable, but whatever return None; }; @@ -645,8 +649,8 @@ pub fn license_version() -> &'static str { #[cfg(test)] mod test { use super::LicenseItem; - use crate::{Expression, license_id}; + use alloc::string::ToString; #[test] fn gnu_or_later_display() { diff --git a/src/licensee.rs b/src/licensee.rs index 6377d55..a510969 100644 --- a/src/licensee.rs +++ b/src/licensee.rs @@ -3,7 +3,8 @@ use crate::{ error::{ParseError, Reason}, lexer::{Lexer, Token}, }; -use std::fmt; +use alloc::{borrow::ToOwned, boxed::Box, string::String}; +use core::fmt; /// A convenience wrapper for a license and optional additional text that can be /// checked against a license requirement to see if it satisfies the requirement @@ -26,7 +27,7 @@ impl fmt::Display for Licensee { } } -impl std::str::FromStr for Licensee { +impl core::str::FromStr for Licensee { type Err = ParseError; fn from_str(s: &str) -> Result { @@ -243,7 +244,7 @@ impl Licensee { impl PartialOrd for Licensee { #[inline] - fn partial_cmp(&self, o: &LicenseReq) -> Option { + fn partial_cmp(&self, o: &LicenseReq) -> Option { self.inner.partial_cmp(o) } } @@ -267,6 +268,7 @@ mod test { use crate::{ AdditionItem, LicenseItem, LicenseRef, LicenseReq, Licensee, exception_id, license_id, }; + use alloc::{borrow::ToOwned, boxed::Box, vec::Vec}; const LICENSEES: &[&str] = &[ "LicenseRef-Embark-Proprietary",