From ee7d5f779ac0613d4053c845ce99e7fb04fbfe9c Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 29 Apr 2021 14:39:12 +0200 Subject: [PATCH 1/3] No_std Signed-off-by: Francesco Guardiani --- .github/workflows/rust_tests.yml | 16 ++++ Cargo.toml | 14 +++- src/event/attributes.rs | 50 ++++++------ src/event/builder.rs | 8 +- src/event/mod.rs | 14 ++-- src/event/types.rs | 134 +++++++++++++++++++++---------- src/event/v03/attributes.rs | 11 ++- src/event/v03/builder.rs | 14 ++-- src/event/v03/format.rs | 5 +- src/event/v10/attributes.rs | 9 +-- src/event/v10/builder.rs | 13 ++- src/event/v10/format.rs | 5 +- src/lib.rs | 11 ++- src/message/error.rs | 3 +- src/message/types.rs | 13 ++- 15 files changed, 192 insertions(+), 128 deletions(-) diff --git a/.github/workflows/rust_tests.yml b/.github/workflows/rust_tests.yml index 3c7db15c..acd01481 100644 --- a/.github/workflows/rust_tests.yml +++ b/.github/workflows/rust_tests.yml @@ -67,6 +67,22 @@ jobs: toolchain: ${{ matrix.toolchain }} args: --target ${{ matrix.target }} --all-features + # If glibc, compile and test only the core module with no_std + - uses: actions-rs/cargo@v1 + name: "Build" + if: matrix.target == 'x86_64-unknown-linux-gnu' + with: + command: build + toolchain: ${{ matrix.toolchain }} + args: --target ${{ matrix.target }} --package cloudevents-sdk --workspace --no-default-features + - uses: actions-rs/cargo@v1 + name: "Test" + if: matrix.target == 'x86_64-unknown-linux-gnu' + with: + command: test + toolchain: ${{ matrix.toolchain }} + args: --target ${{ matrix.target }} --package cloudevents-sdk --workspace --no-default-features + # If musl, compile and test all - uses: actions-rs/cargo@v1 name: "Build" diff --git a/Cargo.toml b/Cargo.toml index 95db9b34..f1305718 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/cloudevents/sdk-rust" exclude = [ ".github/*" ] -categories = ["web-programming", "encoding", "data-structures"] +categories = ["web-programming", "encoding", "data-structures", "no_std"] [lib] name = "cloudevents" @@ -28,9 +28,15 @@ serde_json = "^1.0" chrono = { version = "^0.4", features = ["serde"] } delegate-attr = "^0.2" base64 = "^0.12" -url = { version = "^2.1", features = ["serde"] } -snafu = "^0.6" +snafu = { version = "^0.6", default-features = false} bitflags = "^1.2" +url = { version = "^2.1", features = ["serde"], optional = true } + +[features] +# Without default features, the package acts as no_std +default = ["std"] + +std = ["snafu/std", "url"] # runtime optional deps actix-web = { version = "^3", default-features = false, optional = true } @@ -49,7 +55,7 @@ hostname = "^0.3" uuid = { version = "^0.8", features = ["v4"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -web-sys = { version = "^0.3", features = ["Window", "Location"] } +web-sys = { version = "^0.3", default-features = false, features = ["Window", "Location"] } uuid = { version = "^0.8", features = ["v4", "wasm-bindgen"] } [dev-dependencies] diff --git a/src/event/attributes.rs b/src/event/attributes.rs index 30c1d304..c4070f4e 100644 --- a/src/event/attributes.rs +++ b/src/event/attributes.rs @@ -1,11 +1,11 @@ use super::{ AttributesIntoIteratorV03, AttributesIntoIteratorV10, AttributesV03, AttributesV10, - ExtensionValue, SpecVersion, UriReference, + ExtensionValue, SpecVersion, + types::* }; use chrono::{DateTime, Utc}; use serde::Serializer; use std::fmt; -use url::Url; /// Enum representing a borrowed value of a CloudEvent attribute. /// This represents the types defined in the [CloudEvent spec type system](https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system) @@ -13,7 +13,7 @@ use url::Url; pub enum AttributeValue<'a> { SpecVersion(SpecVersion), String(&'a str), - URI(&'a Url), + URI(&'a Uri), URIRef(&'a UriReference), Boolean(&'a bool), Integer(&'a i64), @@ -57,7 +57,7 @@ pub trait AttributesReader { /// Get the [datacontenttype](https://github.com/cloudevents/spec/blob/master/spec.md#datacontenttype). fn datacontenttype(&self) -> Option<&str>; /// Get the [dataschema](https://github.com/cloudevents/spec/blob/master/spec.md#dataschema). - fn dataschema(&self) -> Option<&Url>; + fn dataschema(&self) -> Option<&Uri>; /// Get the [subject](https://github.com/cloudevents/spec/blob/master/spec.md#subject). fn subject(&self) -> Option<&str>; /// Get the [time](https://github.com/cloudevents/spec/blob/master/spec.md#time). @@ -87,7 +87,7 @@ pub trait AttributesWriter { -> Option; /// Set the [dataschema](https://github.com/cloudevents/spec/blob/master/spec.md#dataschema). /// Returns the previous value. - fn set_dataschema(&mut self, dataschema: Option>) -> Option; + fn set_dataschema(&mut self, dataschema: Option>) -> Option; } pub(crate) trait AttributesConverter { @@ -154,7 +154,7 @@ impl AttributesReader for Attributes { } } - fn dataschema(&self) -> Option<&Url> { + fn dataschema(&self) -> Option<&Uri> { match self { Attributes::V03(a) => a.dataschema(), Attributes::V10(a) => a.dataschema(), @@ -222,7 +222,7 @@ impl AttributesWriter for Attributes { } } - fn set_dataschema(&mut self, dataschema: Option>) -> Option { + fn set_dataschema(&mut self, dataschema: Option>) -> Option { match self { Attributes::V03(a) => a.set_dataschema(dataschema), Attributes::V10(a) => a.set_dataschema(dataschema), @@ -253,31 +253,27 @@ impl Attributes { } #[cfg(not(target_arch = "wasm32"))] -pub(crate) fn default_hostname() -> Url { - Url::parse( - format!( - "http://{}", - hostname::get() - .ok() - .map(|s| s.into_string().ok()) - .flatten() - .unwrap_or_else(|| "localhost".to_string()) - ) - .as_ref(), +pub(crate) fn default_hostname() -> Uri { + format!( + "http://{}", + hostname::get() + .ok() + .map(|s| s.into_string().ok()) + .flatten() + .unwrap_or_else(|| "localhost".to_string()) ) + .into_uri() .unwrap() } #[cfg(target_arch = "wasm32")] -pub(crate) fn default_hostname() -> Url { +pub(crate) fn default_hostname() -> Uri { use std::str::FromStr; - Url::from_str( - web_sys::window() - .map(|w| w.location().host().ok()) - .flatten() - .unwrap_or(String::from("http://localhost")) - .as_str(), - ) - .unwrap() + web_sys::window() + .map(|w| w.location().host().ok()) + .flatten() + .unwrap_or(String::from("http://localhost")) + .into_uri() + .unwrap() } diff --git a/src/event/builder.rs b/src/event/builder.rs index c04a18d5..d033a3ec 100644 --- a/src/event/builder.rs +++ b/src/event/builder.rs @@ -1,11 +1,11 @@ -use super::Event; use snafu::Snafu; +use super::Event; +use super::types; /// Trait to implement a builder for [`Event`]: /// ``` /// use cloudevents::event::{EventBuilderV10, EventBuilder}; /// use chrono::Utc; -/// use url::Url; /// /// let event = EventBuilderV10::new() /// .id("my_event.my_application") @@ -48,9 +48,9 @@ pub enum Error { attribute_name, source ))] - ParseUrlError { + ParseUriError { attribute_name: &'static str, - source: url::ParseError, + source: types::ParseUriError, }, #[snafu(display( "Invalid value setting attribute '{}' with uriref type", diff --git a/src/event/mod.rs b/src/event/mod.rs index 157a8b22..c5a29466 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -8,7 +8,7 @@ mod extensions; mod format; mod message; mod spec_version; -mod types; +pub mod types; pub use attributes::Attributes; pub use attributes::{AttributeValue, AttributesReader, AttributesWriter}; @@ -20,7 +20,6 @@ pub(crate) use message::EventBinarySerializer; pub(crate) use message::EventStructuredSerializer; pub use spec_version::SpecVersion; pub use spec_version::UnknownSpecVersion; -pub use types::{TryIntoTime, TryIntoUrl, UriReference}; mod v03; @@ -38,11 +37,10 @@ pub use v10::EventBuilder as EventBuilderV10; pub(crate) use v10::EventFormatDeserializer as EventFormatDeserializerV10; pub(crate) use v10::EventFormatSerializer as EventFormatSerializerV10; -use chrono::{DateTime, Utc}; use delegate_attr::delegate; use std::collections::HashMap; use std::fmt; -use url::Url; +use types::*; /// Data structure that represents a [CloudEvent](https://github.com/cloudevents/spec/blob/master/spec.md). /// It provides methods to get the attributes through [`AttributesReader`] @@ -89,7 +87,7 @@ impl AttributesReader for Event { fn specversion(&self) -> SpecVersion; fn ty(&self) -> &str; fn datacontenttype(&self) -> Option<&str>; - fn dataschema(&self) -> Option<&Url>; + fn dataschema(&self) -> Option<&Uri>; fn subject(&self) -> Option<&str>; fn time(&self) -> Option<&DateTime>; } @@ -103,7 +101,7 @@ impl AttributesWriter for Event { fn set_time(&mut self, time: Option>>) -> Option>; fn set_datacontenttype(&mut self, datacontenttype: Option>) -> Option; - fn set_dataschema(&mut self, dataschema: Option>) -> Option; + fn set_dataschema(&mut self, dataschema: Option>) -> Option; } impl Default for Event { @@ -165,10 +163,10 @@ impl Event { /// /// let (datacontenttype, dataschema, data) = e.take_data(); /// ``` - pub fn take_data(&mut self) -> (Option, Option, Option) { + pub fn take_data(&mut self) -> (Option, Option, Option) { ( self.attributes.set_datacontenttype(None as Option), - self.attributes.set_dataschema(None as Option), + self.attributes.set_dataschema(None as Option), self.data.take(), ) } diff --git a/src/event/types.rs b/src/event/types.rs index db3f3f7d..7bca762c 100644 --- a/src/event/types.rs +++ b/src/event/types.rs @@ -1,60 +1,108 @@ -use chrono::{DateTime, Utc}; -use url::Url; +pub use self::uri::Uri; +pub use self::uri::ParseUriError; +pub use self::uri::TryIntoUri; -/// Trait to define conversion to [`Url`] -pub trait TryIntoUrl { - fn into_url(self) -> Result; -} +pub use urireference::UriReference; + +pub use chrono::{DateTime, Utc}; +pub use time::TryIntoTime; + +mod uri { + #[cfg(feature = "std")] + pub use url::Url as Uri; + #[cfg(not(feature = "std"))] + pub use String as Uri; -impl TryIntoUrl for Url { - fn into_url(self) -> Result { - Ok(self) + #[cfg(feature = "std")] + pub use url::ParseError as ParseUriError; + #[cfg(not(feature = "std"))] + pub use None as ParseUriError; + + /// Trait to define conversion to [`Uri`] + pub trait TryIntoUri { + fn into_uri(self) -> Result; } -} -impl TryIntoUrl for &str { - fn into_url(self) -> Result { - Url::parse(self) + #[cfg(feature = "std")] + impl TryIntoUri for Uri { + fn into_uri(self) -> Result { + Ok(self) + } + } + + #[cfg(feature = "std")] + impl TryIntoUri for &str { + fn into_uri(self) -> Result { + url::Url::parse(self) + } + } + + #[cfg(feature = "std")] + impl TryIntoUri for String { + fn into_uri(self) -> Result { + self.as_str().into_uri() + } } -} -impl TryIntoUrl for String { - fn into_url(self) -> Result { - self.as_str().into_url() + #[cfg(not(feature = "std"))] + impl TryIntoUri for Uri { + fn into_uri(self) -> Result { + Ok(self) + } + } + + #[cfg(not(feature = "std"))] + impl TryIntoUri for &str { + fn into_uri(self) -> Result { + Ok(String::from(self)) + } + } + + #[cfg(not(feature = "std"))] + impl TryIntoUri for String { + fn into_uri(self) -> Result { + Ok(self) + } } } -/// Trait to define conversion to [`DateTime`] -pub trait TryIntoTime { - fn into_time(self) -> Result, chrono::ParseError>; +mod urireference { + /// The URI-reference type. + /// + /// The URI reference can be a URI, or just a relative path. + /// + /// As the [`types::Url`] type can only represent an absolute URL, we are falling back to a string + /// here. + /// + /// Also see: + /// * + /// * + pub type UriReference = String; } -impl TryIntoTime for DateTime { - fn into_time(self) -> Result, chrono::ParseError> { - Ok(self) +mod time { + use chrono::{DateTime, Utc}; + + /// Trait to define conversion to [`DateTime`] + pub trait TryIntoTime { + fn into_time(self) -> Result, chrono::ParseError>; } -} -impl TryIntoTime for &str { - fn into_time(self) -> Result, chrono::ParseError> { - Ok(DateTime::::from(DateTime::parse_from_rfc3339(self)?)) + impl TryIntoTime for DateTime { + fn into_time(self) -> Result, chrono::ParseError> { + Ok(self) + } } -} -impl TryIntoTime for String { - fn into_time(self) -> Result, chrono::ParseError> { - self.as_str().into_time() + impl TryIntoTime for &str { + fn into_time(self) -> Result, chrono::ParseError> { + Ok(DateTime::::from(DateTime::parse_from_rfc3339(self)?)) + } } -} -/// The URI-reference type. -/// -/// The URI reference can be a URI, or just a relative path. -/// -/// As the [`url::Url`] type can only represent an absolute URL, we are falling back to a string -/// here. -/// -/// Also see: -/// * -/// * -pub type UriReference = String; + impl TryIntoTime for String { + fn into_time(self) -> Result, chrono::ParseError> { + self.as_str().into_time() + } + } +} diff --git a/src/event/v03/attributes.rs b/src/event/v03/attributes.rs index 74aafab3..4bd3e439 100644 --- a/src/event/v03/attributes.rs +++ b/src/event/v03/attributes.rs @@ -1,8 +1,7 @@ use crate::event::attributes::{default_hostname, AttributeValue, AttributesConverter}; -use crate::event::{AttributesReader, AttributesV10, AttributesWriter, SpecVersion, UriReference}; +use crate::event::{AttributesReader, AttributesV10, AttributesWriter, SpecVersion}; use crate::message::{BinarySerializer, MessageAttributeValue}; -use chrono::{DateTime, Utc}; -use url::Url; +use crate::event::types::*; use uuid::Uuid; pub(crate) const ATTRIBUTE_NAMES: [&str; 8] = [ @@ -23,7 +22,7 @@ pub struct Attributes { pub(crate) ty: String, pub(crate) source: UriReference, pub(crate) datacontenttype: Option, - pub(crate) schemaurl: Option, + pub(crate) schemaurl: Option, pub(crate) subject: Option, pub(crate) time: Option>, } @@ -105,7 +104,7 @@ impl AttributesReader for Attributes { self.datacontenttype.as_deref() } - fn dataschema(&self) -> Option<&Url> { + fn dataschema(&self) -> Option<&Uri> { self.schemaurl.as_ref() } @@ -146,7 +145,7 @@ impl AttributesWriter for Attributes { std::mem::replace(&mut self.datacontenttype, datacontenttype.map(Into::into)) } - fn set_dataschema(&mut self, dataschema: Option>) -> Option { + fn set_dataschema(&mut self, dataschema: Option>) -> Option { std::mem::replace(&mut self.schemaurl, dataschema.map(Into::into)) } } diff --git a/src/event/v03/builder.rs b/src/event/v03/builder.rs index 734245ad..d867b797 100644 --- a/src/event/v03/builder.rs +++ b/src/event/v03/builder.rs @@ -1,13 +1,11 @@ use super::Attributes as AttributesV03; use crate::event::{ - Attributes, Data, Event, EventBuilderError, ExtensionValue, TryIntoTime, TryIntoUrl, - UriReference, + Attributes, Data, Event, EventBuilderError, ExtensionValue }; use crate::message::MessageAttributeValue; -use chrono::{DateTime, Utc}; +use crate::event::types::*; use std::collections::HashMap; use std::convert::TryInto; -use url::Url; /// Builder to create a CloudEvent V0.3 #[derive(Clone, Debug)] @@ -16,7 +14,7 @@ pub struct EventBuilder { ty: Option, source: Option, datacontenttype: Option, - schemaurl: Option, + schemaurl: Option, subject: Option, time: Option>, data: Option, @@ -89,14 +87,14 @@ impl EventBuilder { pub fn data_with_schema( mut self, datacontenttype: impl Into, - schemaurl: impl TryIntoUrl, + schemaurl: impl TryIntoUri, data: impl Into, ) -> Self { self.datacontenttype = Some(datacontenttype.into()); - match schemaurl.into_url() { + match schemaurl.into_uri() { Ok(u) => self.schemaurl = Some(u), Err(e) => { - self.error = Some(EventBuilderError::ParseUrlError { + self.error = Some(EventBuilderError::ParseUriError { attribute_name: "schemaurl", source: e, }) diff --git a/src/event/v03/format.rs b/src/event/v03/format.rs index 4cb4de65..d3d3b432 100644 --- a/src/event/v03/format.rs +++ b/src/event/v03/format.rs @@ -1,13 +1,12 @@ use super::Attributes; use crate::event::data::is_json_content_type; use crate::event::{Data, ExtensionValue}; -use chrono::{DateTime, Utc}; +use crate::event::types::*; use serde::de::IntoDeserializer; use serde::ser::SerializeMap; use serde::{Deserialize, Serializer}; use serde_json::{Map, Value}; use std::collections::HashMap; -use url::Url; pub(crate) struct EventFormatDeserializer {} @@ -21,7 +20,7 @@ impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer { source: extract_field!(map, "source", String, E)?, datacontenttype: extract_optional_field!(map, "datacontenttype", String, E)?, schemaurl: extract_optional_field!(map, "schemaurl", String, E, |s: String| { - Url::parse(&s) + s.into_uri() })?, subject: extract_optional_field!(map, "subject", String, E)?, time: extract_optional_field!(map, "time", String, E, |s: String| { diff --git a/src/event/v10/attributes.rs b/src/event/v10/attributes.rs index 428f6c67..630ddcc6 100644 --- a/src/event/v10/attributes.rs +++ b/src/event/v10/attributes.rs @@ -1,9 +1,8 @@ use crate::event::attributes::{default_hostname, AttributeValue, AttributesConverter}; use crate::event::{AttributesReader, AttributesV03, AttributesWriter, SpecVersion, UriReference}; use crate::message::{BinarySerializer, MessageAttributeValue}; -use chrono::{DateTime, Utc}; +use crate::event::types::*; use core::fmt::Debug; -use url::Url; use uuid::Uuid; pub(crate) const ATTRIBUTE_NAMES: [&str; 8] = [ @@ -24,7 +23,7 @@ pub struct Attributes { pub(crate) ty: String, pub(crate) source: UriReference, pub(crate) datacontenttype: Option, - pub(crate) dataschema: Option, + pub(crate) dataschema: Option, pub(crate) subject: Option, pub(crate) time: Option>, } @@ -106,7 +105,7 @@ impl AttributesReader for Attributes { self.datacontenttype.as_deref() } - fn dataschema(&self) -> Option<&Url> { + fn dataschema(&self) -> Option<&Uri> { self.dataschema.as_ref() } @@ -147,7 +146,7 @@ impl AttributesWriter for Attributes { std::mem::replace(&mut self.datacontenttype, datacontenttype.map(Into::into)) } - fn set_dataschema(&mut self, dataschema: Option>) -> Option { + fn set_dataschema(&mut self, dataschema: Option>) -> Option { std::mem::replace(&mut self.dataschema, dataschema.map(Into::into)) } } diff --git a/src/event/v10/builder.rs b/src/event/v10/builder.rs index 0ef25f9b..1568f854 100644 --- a/src/event/v10/builder.rs +++ b/src/event/v10/builder.rs @@ -1,13 +1,12 @@ use super::Attributes as AttributesV10; use crate::event::{ - Attributes, Data, Event, EventBuilderError, ExtensionValue, TryIntoTime, TryIntoUrl, + Attributes, Data, Event, EventBuilderError, ExtensionValue, TryIntoTime, TryIntoUri, UriReference, }; use crate::message::MessageAttributeValue; -use chrono::{DateTime, Utc}; +use crate::event::types::*; use std::collections::HashMap; use std::convert::TryInto; -use url::Url; /// Builder to create a CloudEvent V1.0 #[derive(Clone, Debug)] @@ -16,7 +15,7 @@ pub struct EventBuilder { ty: Option, source: Option, datacontenttype: Option, - dataschema: Option, + dataschema: Option, subject: Option, time: Option>, data: Option, @@ -89,14 +88,14 @@ impl EventBuilder { pub fn data_with_schema( mut self, datacontenttype: impl Into, - schemaurl: impl TryIntoUrl, + schemaurl: impl TryIntoUri, data: impl Into, ) -> Self { self.datacontenttype = Some(datacontenttype.into()); - match schemaurl.into_url() { + match schemaurl.into_uri() { Ok(u) => self.dataschema = Some(u), Err(e) => { - self.error = Some(EventBuilderError::ParseUrlError { + self.error = Some(EventBuilderError::ParseUriError { attribute_name: "dataschema", source: e, }) diff --git a/src/event/v10/format.rs b/src/event/v10/format.rs index 50f1e361..11f9353d 100644 --- a/src/event/v10/format.rs +++ b/src/event/v10/format.rs @@ -1,13 +1,12 @@ use super::Attributes; use crate::event::data::is_json_content_type; use crate::event::{Data, ExtensionValue}; -use chrono::{DateTime, Utc}; +use crate::event::types::*; use serde::de::IntoDeserializer; use serde::ser::SerializeMap; use serde::{Deserialize, Serializer}; use serde_json::{Map, Value}; use std::collections::HashMap; -use url::Url; pub(crate) struct EventFormatDeserializer {} @@ -21,7 +20,7 @@ impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer { source: extract_field!(map, "source", String, E)?, datacontenttype: extract_optional_field!(map, "datacontenttype", String, E)?, dataschema: extract_optional_field!(map, "dataschema", String, E, |s: String| { - Url::parse(&s) + s.into_uri() })?, subject: extract_optional_field!(map, "subject", String, E)?, time: extract_optional_field!(map, "time", String, E, |s: String| { diff --git a/src/lib.rs b/src/lib.rs index 86d93760..9f1eb3f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,7 @@ //! # use std::error::Error; //! # fn main() -> Result<(), Box> { //! use cloudevents::{EventBuilder, AttributesReader, EventBuilderV10}; -//! use chrono::{Utc, DateTime}; -//! use url::Url; +//! use chrono::Utc; //! //! let event = EventBuilderV10::new() //! .id("my_event.my_application") @@ -54,6 +53,14 @@ //! [Responders]: https://actix.rs/docs/handlers/ #![deny(broken_intra_doc_links)] +#![cfg_attr(not(any(feature = "std", test)), no_std)] + +#[cfg(feature = "alloc")] +extern crate alloc; +#[cfg(all(feature = "std", not(feature = "alloc")))] +extern crate std as alloc; +#[cfg(any(feature = "std", test))] +extern crate std as core; pub mod binding; pub mod event; diff --git a/src/message/error.rs b/src/message/error.rs index 900ae584..09dfbd53 100644 --- a/src/message/error.rs +++ b/src/message/error.rs @@ -1,4 +1,5 @@ use snafu::Snafu; +use crate::event::types; /// Represents an error during serialization/deserialization process #[derive(Debug, Snafu)] @@ -22,7 +23,7 @@ pub enum Error { ParseTimeError { source: chrono::ParseError }, #[snafu(display("Error while parsing a url: {}", source))] #[snafu(context(false))] - ParseUrlError { source: url::ParseError }, + ParseUrlError { source: types::ParseUriError }, #[snafu(display("Error while decoding base64: {}", source))] #[snafu(context(false))] Base64DecodingError { source: base64::DecodeError }, diff --git a/src/message/types.rs b/src/message/types.rs index c37f4c34..34f69b63 100644 --- a/src/message/types.rs +++ b/src/message/types.rs @@ -1,8 +1,7 @@ -use crate::event::{ExtensionValue, UriReference}; -use chrono::{DateTime, Utc}; +use crate::event::ExtensionValue; use std::convert::TryInto; use std::fmt; -use url::Url; +use crate::event::types::*; /// Union type representing a [CloudEvent context attribute type](https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system). #[derive(PartialEq, Eq, Debug, Clone)] @@ -11,7 +10,7 @@ pub enum MessageAttributeValue { Integer(i64), String(String), Binary(Vec), - Uri(Url), + Uri(Uri), UriRef(UriReference), DateTime(DateTime), } @@ -29,13 +28,13 @@ impl TryInto> for MessageAttributeValue { } } -impl TryInto for MessageAttributeValue { +impl TryInto for MessageAttributeValue { type Error = super::Error; - fn try_into(self) -> Result { + fn try_into(self) -> Result { match self { MessageAttributeValue::Uri(u) => Ok(u), - v => Ok(Url::parse(v.to_string().as_ref())?), + v => Ok(v.to_string().into_uri()?), } } } From 94c3f12c5744853b406b72bc3b6d2d74150ebfc5 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 29 Apr 2021 14:52:52 +0200 Subject: [PATCH 2/3] fmt Signed-off-by: Francesco Guardiani --- src/event/attributes.rs | 3 +-- src/event/builder.rs | 4 ++-- src/event/types.rs | 2 +- src/event/v03/attributes.rs | 2 +- src/event/v03/builder.rs | 6 ++---- src/event/v03/format.rs | 2 +- src/event/v10/attributes.rs | 2 +- src/event/v10/builder.rs | 2 +- src/event/v10/format.rs | 2 +- src/message/error.rs | 2 +- src/message/types.rs | 2 +- 11 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/event/attributes.rs b/src/event/attributes.rs index c4070f4e..58d315cb 100644 --- a/src/event/attributes.rs +++ b/src/event/attributes.rs @@ -1,7 +1,6 @@ use super::{ - AttributesIntoIteratorV03, AttributesIntoIteratorV10, AttributesV03, AttributesV10, + types::*, AttributesIntoIteratorV03, AttributesIntoIteratorV10, AttributesV03, AttributesV10, ExtensionValue, SpecVersion, - types::* }; use chrono::{DateTime, Utc}; use serde::Serializer; diff --git a/src/event/builder.rs b/src/event/builder.rs index d033a3ec..9ae7b75c 100644 --- a/src/event/builder.rs +++ b/src/event/builder.rs @@ -1,6 +1,6 @@ -use snafu::Snafu; -use super::Event; use super::types; +use super::Event; +use snafu::Snafu; /// Trait to implement a builder for [`Event`]: /// ``` diff --git a/src/event/types.rs b/src/event/types.rs index 7bca762c..c15e70ab 100644 --- a/src/event/types.rs +++ b/src/event/types.rs @@ -1,6 +1,6 @@ -pub use self::uri::Uri; pub use self::uri::ParseUriError; pub use self::uri::TryIntoUri; +pub use self::uri::Uri; pub use urireference::UriReference; diff --git a/src/event/v03/attributes.rs b/src/event/v03/attributes.rs index 4bd3e439..a887b9e3 100644 --- a/src/event/v03/attributes.rs +++ b/src/event/v03/attributes.rs @@ -1,7 +1,7 @@ use crate::event::attributes::{default_hostname, AttributeValue, AttributesConverter}; +use crate::event::types::*; use crate::event::{AttributesReader, AttributesV10, AttributesWriter, SpecVersion}; use crate::message::{BinarySerializer, MessageAttributeValue}; -use crate::event::types::*; use uuid::Uuid; pub(crate) const ATTRIBUTE_NAMES: [&str; 8] = [ diff --git a/src/event/v03/builder.rs b/src/event/v03/builder.rs index d867b797..7d005425 100644 --- a/src/event/v03/builder.rs +++ b/src/event/v03/builder.rs @@ -1,9 +1,7 @@ use super::Attributes as AttributesV03; -use crate::event::{ - Attributes, Data, Event, EventBuilderError, ExtensionValue -}; -use crate::message::MessageAttributeValue; use crate::event::types::*; +use crate::event::{Attributes, Data, Event, EventBuilderError, ExtensionValue}; +use crate::message::MessageAttributeValue; use std::collections::HashMap; use std::convert::TryInto; diff --git a/src/event/v03/format.rs b/src/event/v03/format.rs index d3d3b432..1a402ae2 100644 --- a/src/event/v03/format.rs +++ b/src/event/v03/format.rs @@ -1,7 +1,7 @@ use super::Attributes; use crate::event::data::is_json_content_type; -use crate::event::{Data, ExtensionValue}; use crate::event::types::*; +use crate::event::{Data, ExtensionValue}; use serde::de::IntoDeserializer; use serde::ser::SerializeMap; use serde::{Deserialize, Serializer}; diff --git a/src/event/v10/attributes.rs b/src/event/v10/attributes.rs index 630ddcc6..34557d9d 100644 --- a/src/event/v10/attributes.rs +++ b/src/event/v10/attributes.rs @@ -1,7 +1,7 @@ use crate::event::attributes::{default_hostname, AttributeValue, AttributesConverter}; +use crate::event::types::*; use crate::event::{AttributesReader, AttributesV03, AttributesWriter, SpecVersion, UriReference}; use crate::message::{BinarySerializer, MessageAttributeValue}; -use crate::event::types::*; use core::fmt::Debug; use uuid::Uuid; diff --git a/src/event/v10/builder.rs b/src/event/v10/builder.rs index 1568f854..8c86e762 100644 --- a/src/event/v10/builder.rs +++ b/src/event/v10/builder.rs @@ -1,10 +1,10 @@ use super::Attributes as AttributesV10; +use crate::event::types::*; use crate::event::{ Attributes, Data, Event, EventBuilderError, ExtensionValue, TryIntoTime, TryIntoUri, UriReference, }; use crate::message::MessageAttributeValue; -use crate::event::types::*; use std::collections::HashMap; use std::convert::TryInto; diff --git a/src/event/v10/format.rs b/src/event/v10/format.rs index 11f9353d..3719aa71 100644 --- a/src/event/v10/format.rs +++ b/src/event/v10/format.rs @@ -1,7 +1,7 @@ use super::Attributes; use crate::event::data::is_json_content_type; -use crate::event::{Data, ExtensionValue}; use crate::event::types::*; +use crate::event::{Data, ExtensionValue}; use serde::de::IntoDeserializer; use serde::ser::SerializeMap; use serde::{Deserialize, Serializer}; diff --git a/src/message/error.rs b/src/message/error.rs index 09dfbd53..8e478f31 100644 --- a/src/message/error.rs +++ b/src/message/error.rs @@ -1,5 +1,5 @@ -use snafu::Snafu; use crate::event::types; +use snafu::Snafu; /// Represents an error during serialization/deserialization process #[derive(Debug, Snafu)] diff --git a/src/message/types.rs b/src/message/types.rs index 34f69b63..066e04d3 100644 --- a/src/message/types.rs +++ b/src/message/types.rs @@ -1,7 +1,7 @@ +use crate::event::types::*; use crate::event::ExtensionValue; use std::convert::TryInto; use std::fmt; -use crate::event::types::*; /// Union type representing a [CloudEvent context attribute type](https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system). #[derive(PartialEq, Eq, Debug, Clone)] From 6d07bcde93579d8f001ca09ae9637ed928aeb631 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Wed, 7 Jul 2021 11:13:39 +0200 Subject: [PATCH 3/3] WIP Signed-off-by: Francesco Guardiani --- .github/workflows/rust_tests.yml | 48 +++++++++++++-------- Cargo.toml | 13 +++--- example-projects/no-std-example/Cargo.toml | 15 +++++++ example-projects/no-std-example/src/main.rs | 25 +++++++++++ src/lib.rs | 3 ++ 5 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 example-projects/no-std-example/Cargo.toml create mode 100644 example-projects/no-std-example/src/main.rs diff --git a/.github/workflows/rust_tests.yml b/.github/workflows/rust_tests.yml index acd01481..3b50e227 100644 --- a/.github/workflows/rust_tests.yml +++ b/.github/workflows/rust_tests.yml @@ -53,36 +53,20 @@ jobs: # If glibc, compile and test all - uses: actions-rs/cargo@v1 - name: "Build" + name: "Build glibc" if: matrix.target == 'x86_64-unknown-linux-gnu' with: command: build toolchain: ${{ matrix.toolchain }} args: --target ${{ matrix.target }} --all-features - uses: actions-rs/cargo@v1 - name: "Test" + name: "Test glibc" if: matrix.target == 'x86_64-unknown-linux-gnu' with: command: test toolchain: ${{ matrix.toolchain }} args: --target ${{ matrix.target }} --all-features - # If glibc, compile and test only the core module with no_std - - uses: actions-rs/cargo@v1 - name: "Build" - if: matrix.target == 'x86_64-unknown-linux-gnu' - with: - command: build - toolchain: ${{ matrix.toolchain }} - args: --target ${{ matrix.target }} --package cloudevents-sdk --workspace --no-default-features - - uses: actions-rs/cargo@v1 - name: "Test" - if: matrix.target == 'x86_64-unknown-linux-gnu' - with: - command: test - toolchain: ${{ matrix.toolchain }} - args: --target ${{ matrix.target }} --package cloudevents-sdk --workspace --no-default-features - # If musl, compile and test all - uses: actions-rs/cargo@v1 name: "Build" @@ -145,3 +129,31 @@ jobs: command: build toolchain: ${{ matrix.toolchain }} args: --target ${{ matrix.target }} --manifest-path ./example-projects/warp-example/Cargo.toml + + check_no_std: + name: Check no_std + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + # Caching stuff + - uses: actions/cache@v2 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: ${{ runner.os }}-cargo-no-std-deps-${{ hashFiles('**/Cargo.toml') }} + - uses: actions/cache@v2 + with: + path: | + target/ + key: ${{ runner.os }}-cargo-no-std-build-${{ hashFiles('**/Cargo.toml') }} + - name: Download cargo-nono + run: curl -LSfs https://japaric.github.io/trust/install.sh | sh -s -- --git hobofan/cargo-nono + - name: Run check + run: ./cargo-nono check diff --git a/Cargo.toml b/Cargo.toml index f1305718..abf3e80e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,11 @@ categories = ["web-programming", "encoding", "data-structures", "no_std"] name = "cloudevents" [features] +# Without default features, the package acts as no_std +default = ["std"] + +std = ["snafu/std", "url"] + actix = ["actix-web", "async-trait", "lazy_static", "bytes", "futures"] reqwest = ["reqwest-lib", "async-trait", "lazy_static", "bytes"] rdkafka = ["rdkafka-lib", "lazy_static", "bytes", "futures"] @@ -28,16 +33,10 @@ serde_json = "^1.0" chrono = { version = "^0.4", features = ["serde"] } delegate-attr = "^0.2" base64 = "^0.12" -snafu = { version = "^0.6", default-features = false} +snafu = { version = "^0.6", default-features = false } bitflags = "^1.2" url = { version = "^2.1", features = ["serde"], optional = true } -[features] -# Without default features, the package acts as no_std -default = ["std"] - -std = ["snafu/std", "url"] - # runtime optional deps actix-web = { version = "^3", default-features = false, optional = true } reqwest-lib = { version = "^0.11", default-features = false, features = ["rustls-tls"], optional = true, package = "reqwest" } diff --git a/example-projects/no-std-example/Cargo.toml b/example-projects/no-std-example/Cargo.toml new file mode 100644 index 00000000..35bae0d7 --- /dev/null +++ b/example-projects/no-std-example/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "no-std-example" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cloudevents-sdk = { path = "../..", default-features = false } + +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" \ No newline at end of file diff --git a/example-projects/no-std-example/src/main.rs b/example-projects/no-std-example/src/main.rs new file mode 100644 index 00000000..f1946219 --- /dev/null +++ b/example-projects/no-std-example/src/main.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +use cloudevents; +use cloudevents::EventBuilder; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} + +#[no_mangle] +pub extern "C" fn _start() -> ! { + loop { + #[allow(dead_code)] + let event = cloudevents::EventBuilderV10::new() + .id("my_id") + .source("my_source") + .subject("some_subject") + .build() + .unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs index 9f1eb3f8..cfaf10f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,7 @@ //! [Responders]: https://actix.rs/docs/handlers/ #![deny(broken_intra_doc_links)] + #![cfg_attr(not(any(feature = "std", test)), no_std)] #[cfg(feature = "alloc")] @@ -62,7 +63,9 @@ extern crate std as alloc; #[cfg(any(feature = "std", test))] extern crate std as core; +#[cfg(feature = "std")] pub mod binding; + pub mod event; pub mod message;