diff --git a/Cargo.lock b/Cargo.lock index 1d443b2..ae0cd4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -339,7 +339,7 @@ checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "libhaystack" -version = "1.0.9" +version = "1.0.10" dependencies = [ "chrono", "chrono-tz", @@ -678,9 +678,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "syn" diff --git a/Cargo.toml b/Cargo.toml index 4b539e2..4786c44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libhaystack" -version = "1.0.9" +version = "1.0.10" description = "Rust implementation of the Haystack 4 data types, defs, filter, units, and encodings" authors = ["J2 Innovations", "Radu Racariu "] edition = "2021" @@ -36,11 +36,14 @@ c-api-zinc = ["zinc"] c-api-json = ["json"] # Lib features -filter = ["defs", "zinc-decoding"] -defs = [] -units = [] -timezone = [] -encoders = ["json", "zinc"] +value = ["units", "timezone", "encoders"] +filter = ["value", "defs", "zinc-decoding"] +defs = ["value"] +units = ["units-db"] +units-db = [] +timezone = ["timezone-db"] +timezone-db = [] +encoders = ["value", "json", "zinc"] json = ["json-encoding", "json-decoding"] json-encoding = [] json-decoding = [] diff --git a/src/haystack/defs/namespace.rs b/src/haystack/defs/namespace.rs index aabefa7..3826129 100644 --- a/src/haystack/defs/namespace.rs +++ b/src/haystack/defs/namespace.rs @@ -3,6 +3,7 @@ //! Haystack Def namespace use dashmap::{mapref::one::Ref as MapReadRef, DashMap}; +use lazy_static::lazy_static; use std::collections::{BTreeMap, HashSet}; use super::misc::parse_multi_line_string_to_dicts; diff --git a/src/haystack/filter/parser.rs b/src/haystack/filter/parser.rs index bcc146c..6af1485 100644 --- a/src/haystack/filter/parser.rs +++ b/src/haystack/filter/parser.rs @@ -7,6 +7,7 @@ use super::nodes::*; use super::path::Path; use crate::haystack::encoding::zinc::decode::scanner::Scanner; use crate::val::{Symbol, Value}; +use lazy_static::lazy_static; use std::io::{Error, Read}; diff --git a/src/haystack/mod.rs b/src/haystack/mod.rs index 91104e9..b9dd841 100644 --- a/src/haystack/mod.rs +++ b/src/haystack/mod.rs @@ -15,6 +15,9 @@ pub mod defs; pub mod encoding; #[cfg(feature = "filter")] pub mod filter; +#[cfg(feature = "timezone")] pub mod timezone; +#[cfg(feature = "units")] pub mod units; +#[cfg(feature = "value")] pub mod val; diff --git a/src/haystack/timezone/iana.rs b/src/haystack/timezone/iana.rs index 8f2be3e..8755b84 100644 --- a/src/haystack/timezone/iana.rs +++ b/src/haystack/timezone/iana.rs @@ -10,9 +10,9 @@ use chrono_tz::{OffsetName, Tz, UTC}; use crate::timezone::fixed_timezone; /// DateTime type that supports timezones -pub(crate) type DateTimeType = StdDateTime; +pub type DateTimeType = StdDateTime; -pub(crate) fn make_date_time(date: StdDateTime) -> Result { +pub fn make_date_time(date: StdDateTime) -> Result { use chrono::LocalResult; if let Ok(tz) = find_timezone(&fixed_timezone(&date.offset().to_string())) { Ok(match tz.from_local_datetime(&date.naive_local()) { @@ -37,15 +37,15 @@ pub fn make_date_time_with_tz( } } -pub(crate) fn utc_now() -> DateTimeType { +pub fn utc_now() -> DateTimeType { Utc::now().with_timezone(&UTC) } -pub(crate) fn is_utc(date: &DateTimeType) -> bool { +pub fn is_utc(date: &DateTimeType) -> bool { date.timezone() == UTC } -pub(crate) fn timezone_short_name(date: &DateTimeType) -> String { +pub fn timezone_short_name(date: &DateTimeType) -> String { let tz_id = date.offset().tz_id(); tz_id[tz_id.find('/').map_or(0, |v| v + 1)..].to_string() diff --git a/src/haystack/timezone/mod.rs b/src/haystack/timezone/mod.rs index 2054882..78e0d0c 100644 --- a/src/haystack/timezone/mod.rs +++ b/src/haystack/timezone/mod.rs @@ -6,14 +6,14 @@ //! provided by [chrono_tz](https://crates.io/crates/chrono-tz), or by just using a fixed offset datetime //! by toggling the `timezone` feature. -#[cfg(feature = "timezone")] +#[cfg(feature = "timezone-db")] pub mod iana; -#[cfg(feature = "timezone")] -pub(crate) use iana::*; -#[cfg(not(feature = "timezone"))] +#[cfg(feature = "timezone-db")] +pub use iana::*; +#[cfg(not(feature = "timezone-db"))] pub mod utc; -#[cfg(not(feature = "timezone"))] -pub(crate) use utc::*; +#[cfg(not(feature = "timezone-db"))] +pub use utc::*; pub(super) fn fixed_timezone(offset: &str) -> String { let gmt_offset = offset[2..offset.find(':').unwrap_or(3)].to_string(); diff --git a/src/haystack/timezone/utc.rs b/src/haystack/timezone/utc.rs index ef0ebc6..042c087 100644 --- a/src/haystack/timezone/utc.rs +++ b/src/haystack/timezone/utc.rs @@ -6,35 +6,32 @@ use crate::timezone::fixed_timezone; use chrono::{DateTime as StdDateTime, FixedOffset, TimeZone, Utc}; /// DateTime type that works with a fixed offset -pub(crate) type DateTimeType = StdDateTime; +pub type DateTimeType = StdDateTime; -pub(crate) fn make_date_time(value: DateTimeType) -> Result { +pub fn make_date_time(value: DateTimeType) -> Result { Ok(value) } /// Constructs an UTC datetime as the timezones are not available /// in this configuration. -pub(crate) fn make_date_time_with_tz( - datetime: &DateTimeType, - _tz: &str, -) -> Result { +pub fn make_date_time_with_tz(datetime: &DateTimeType, _tz: &str) -> Result { use chrono::Offset; Ok(Utc .from_utc_datetime(&datetime.naive_utc()) .with_timezone(&Utc.fix())) } -pub(crate) fn utc_now() -> DateTimeType { +pub fn utc_now() -> DateTimeType { Utc::now().into() } -pub(crate) fn is_utc(date: &DateTimeType) -> bool { +pub fn is_utc(date: &DateTimeType) -> bool { use chrono::Offset; &Utc.fix() == date.offset() } -pub(crate) fn timezone_short_name(date: &DateTimeType) -> String { +pub fn timezone_short_name(date: &DateTimeType) -> String { let tz_id = fixed_timezone(&date.offset().to_string()); tz_id[tz_id.find('/').map_or(0, |v| v + 1)..].to_string() diff --git a/src/haystack/units/mod.rs b/src/haystack/units/mod.rs index b3b527b..91cbe35 100644 --- a/src/haystack/units/mod.rs +++ b/src/haystack/units/mod.rs @@ -4,8 +4,9 @@ pub mod unit; pub mod unit_dimension; -#[cfg(feature = "units")] +#[cfg(feature = "units-db")] pub mod units_generated; +use lazy_static::lazy_static; pub use unit::Unit; pub use unit_dimension::UnitDimensions; @@ -13,27 +14,23 @@ pub use unit_dimension::UnitDimensions; /// Get unit by name, if it is defined in the units database #[allow(unused_variables)] pub fn get_unit(unit: &str) -> Option<&'static Unit> { - #[cfg(feature = "units")] + #[cfg(feature = "units-db")] { return units_generated::UNITS.get(unit).copied(); } - #[cfg(not(feature = "units"))] + #[cfg(not(feature = "units-db"))] return None; } /// Tries to get the unit by name, if none is found, return a default unit pub fn get_unit_or_default(unit: &str) -> &'static Unit { - if let Some(unit) = get_unit(unit) { - unit - } else { - &*DEFAULT_UNIT - } + get_unit(unit).unwrap_or(&*DEFAULT_UNIT) } /// Match units for the dimension #[allow(unused_variables)] pub fn match_units(dim: UnitDimensions, scale: f64) -> Vec<&'static Unit> { - #[cfg(feature = "units")] + #[cfg(feature = "units-db")] { units_generated::UNITS .iter() @@ -46,11 +43,11 @@ pub fn match_units(dim: UnitDimensions, scale: f64) -> Vec<&'static Unit> { }) .collect() } - #[cfg(not(feature = "units"))] + #[cfg(not(feature = "units-db"))] return Vec::default(); } -#[cfg(feature = "units")] +#[cfg(feature = "units-db")] fn approx_eq(a: f64, b: f64) -> bool { if a == b { return true; diff --git a/src/haystack/units/unit.rs b/src/haystack/units/unit.rs index 840ea27..48a9bd3 100644 --- a/src/haystack/units/unit.rs +++ b/src/haystack/units/unit.rs @@ -190,6 +190,7 @@ mod test { let meters = get_unit("m").expect("Meters"); let foot = get_unit("ft").expect("Foot"); assert_eq!(meters.convert_to(1.0, foot).map(|f| f.round()), Ok(3.0)); + assert_eq!(foot.convert_to(1.0, meters), Ok(0.3048)); let fahrenheit = get_unit("°F").expect("Fahrenheit"); let celsius = get_unit("°C").expect("Celsius"); diff --git a/src/haystack/units/units_generated.rs b/src/haystack/units/units_generated.rs index 120c527..f7003e2 100644 --- a/src/haystack/units/units_generated.rs +++ b/src/haystack/units/units_generated.rs @@ -3,6 +3,7 @@ #![allow(clippy::approx_constant)] use super::{Unit, UnitDimensions}; +use lazy_static::lazy_static; use std::collections::HashMap; // dimensionless diff --git a/src/lib.rs b/src/lib.rs index fba8f67..f8740b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,11 +14,6 @@ pub mod haystack; pub use haystack::*; -#[cfg(feature = "timezone")] -extern crate chrono_tz; -#[macro_use] -extern crate lazy_static; - #[cfg(target_arch = "wasm32")] extern crate web_sys; diff --git a/unit-gen/src/unit_gen.rs b/unit-gen/src/unit_gen.rs index 3a18176..86237aa 100644 --- a/unit-gen/src/unit_gen.rs +++ b/unit-gen/src/unit_gen.rs @@ -57,6 +57,7 @@ fn gen_file_header() -> String { "\n", "#![allow(clippy::approx_constant)]\n", "use super::{Unit, UnitDimensions};\n", + "use lazy_static::lazy_static;\n", "use std::collections::HashMap;\n" ) .to_string()