From 66a6bdb1b3911b27c2251a31bd5c2b68464193ac Mon Sep 17 00:00:00 2001 From: OliverUv Date: Wed, 1 Feb 2023 01:38:33 +0100 Subject: [PATCH] Add no_std crate support --- .github/workflows/ci.yml | 4 ++++ Cargo.toml | 27 ++++++++++++++++++++++++--- src/errors.rs | 12 +++++++++--- src/lib.rs | 24 ++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85c2537..e3d954e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,3 +18,7 @@ jobs: - run: cargo clippy --all-features -- --deny warnings - run: cargo test --all-features - run: cargo bench --all-features + # For no_std we use check instead of test because + # std is required for the test suite to run. + - run: cargo clippy --no-default-features -- --deny warnings + - run: cargo check --no-default-features diff --git a/Cargo.toml b/Cargo.toml index 0280d5f..dd7be35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,33 @@ readme = "README.md" repository = "https://github.com/jcreekmore/pem-rs.git" version = "1.1.2-alpha.0" categories = [ "cryptography" ] +keywords = [ + "no-std", + "no_std", + "pem", +] edition = "2021" rust-version = "1.67.0" -[dependencies] -base64 = "0.21.0" -serde = { version = "1", optional = true, features = ["serde_derive"] } +[features] +default = ["std"] +std = [ + "base64/std", + # enable serde's std feature iff the serde and std features are both activated + "serde?/std", +] +serde = ["dep:serde"] + +[dependencies.base64] +version = "0.21.0" +default-features = false +features = ["alloc"] + +[dependencies.serde] +version = "1" +optional = true +default-features = false +features = ["serde_derive"] [dev-dependencies] criterion = "0.3.0" diff --git a/src/errors.rs b/src/errors.rs index 27b8491..7bf6ef5 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -3,8 +3,13 @@ // Licensed under the MIT license . This file may not be // copied, modified, or distributed except according to those terms. +use core::fmt; + +#[cfg(any(feature = "std", test))] use std::error::Error; -use std::fmt; + +#[cfg(not(any(feature = "std", test)))] +use alloc::string::String; /// The `pem` error type. #[derive(Debug, Eq, PartialEq)] @@ -16,7 +21,7 @@ pub enum PemError { MissingEndTag, MissingData, InvalidData(::base64::DecodeError), - NotUtf8(::std::str::Utf8Error), + NotUtf8(::core::str::Utf8Error), } impl fmt::Display for PemError { @@ -35,6 +40,7 @@ impl fmt::Display for PemError { } } +#[cfg(any(feature = "std", test))] impl Error for PemError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { @@ -48,4 +54,4 @@ impl Error for PemError { } /// The `pem` result type. -pub type Result = ::std::result::Result; +pub type Result = ::core::result::Result; diff --git a/src/lib.rs b/src/lib.rs index 4bb9b42..75ac618 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,6 +92,17 @@ //! assert_eq!(pems[0].tag(), "INTERMEDIATE CERT"); //! assert_eq!(pems[1].tag(), "CERTIFICATE"); //! ``` +//! +//! # Features +//! +//! This crate supports two features: `std` and `serde`. +//! +//! The `std` feature is enabled by default. If you specify +//! `default-features = false` to disable `std`, be aware that +//! this crate still needs an allocator. +//! +//! The `serde` feature implements `serde::{Deserialize, Serialize}` +//! for this crate's `Pem` struct. #![recursion_limit = "1024"] #![deny( @@ -105,6 +116,16 @@ unused_import_braces, unused_qualifications )] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(any(feature = "std", test)))] +extern crate alloc; +#[cfg(not(any(feature = "std", test)))] +use alloc::{ + format, + string::{String, ToString}, + vec::Vec, +}; mod errors; mod parser; @@ -112,8 +133,7 @@ use parser::{parse_captures, parse_captures_iter, Captures}; pub use crate::errors::{PemError, Result}; use base64::Engine as _; -use std::fmt; -use std::str; +use core::{fmt, str}; /// The line length for PEM encoding const LINE_WRAP: usize = 64;