From da45515ef01e526290f6210bfd05ca79d1294b06 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Tue, 23 May 2023 23:56:15 +0200 Subject: [PATCH 01/14] feat: implement serialize trait for structs --- Cargo.toml | 8 +++++--- src/parse.rs | 2 ++ src/parser.rs | 7 ++++--- src/sentences/aam.rs | 3 ++- src/sentences/alm.rs | 3 ++- src/sentences/bod.rs | 3 ++- src/sentences/bwc.rs | 3 ++- src/sentences/bww.rs | 3 ++- src/sentences/dbk.rs | 3 ++- src/sentences/faa_mode.rs | 5 +++-- src/sentences/fix_type.rs | 4 +++- src/sentences/gbs.rs | 3 ++- src/sentences/gga.rs | 3 ++- src/sentences/gll.rs | 3 ++- src/sentences/gns.rs | 5 +++-- src/sentences/gnss_type.rs | 6 +++--- src/sentences/gsa.rs | 7 ++++--- src/sentences/gsv.rs | 3 ++- src/sentences/hdt.rs | 3 ++- src/sentences/mda.rs | 3 ++- src/sentences/mod.rs | 2 +- src/sentences/mtw.rs | 5 +++-- src/sentences/mwv.rs | 7 ++++--- src/sentences/rmc.rs | 7 ++++--- src/sentences/rmz.rs | 5 +++-- src/sentences/txt.rs | 3 ++- src/sentences/vhw.rs | 3 ++- src/sentences/vtg.rs | 3 ++- src/sentences/zda.rs | 3 ++- src/sentences/zfo.rs | 5 ++++- src/sentences/ztg.rs | 5 ++++- 31 files changed, 82 insertions(+), 46 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e17c89d..9edaaf5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,14 +26,16 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -arrayvec = { version = "0.7.2", default-features = false } -chrono = { version = "0.4.19", default-features = false } -heapless = "0.7.15" +arrayvec = { version = "0.7.2", default-features = false, features = ["serde"]} +chrono = { version = "0.4.19", default-features = false, features = ["serde"] } +heapless = { version ="0.7.15", features = ["serde"]} nom = { version = "7.1.1", default-features = false } # we include num-traits only when `std` is not enabled # because of `fract()` and `trunc()` methods num-traits = { version = "0.2", default-features = false } +serde = { version = "1.0.163", features = ["derive"], default-features = false } +serde_with = { version = "3.0.0", default-features = false, features = ["macros", "chrono"] } [dev-dependencies] approx = "0.5.1" diff --git a/src/parse.rs b/src/parse.rs index 731cd99..6d3f95b 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -7,6 +7,7 @@ use nom::{ sequence::preceded, IResult, }; +use serde::Serialize; use crate::{sentences::*, Error, SentenceType}; @@ -33,6 +34,7 @@ pub const SENTENCE_MAX_LEN: usize = 102; pub const TEXT_PARAMETER_MAX_LEN: usize = 64; /// A known and parsable Nmea sentence type. +#[derive(Serialize)] pub struct NmeaSentence<'a> { pub talker_id: &'a str, pub message_id: SentenceType, diff --git a/src/parser.rs b/src/parser.rs index 4e49f54..a49a059 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4,6 +4,7 @@ use core::{fmt, mem, ops::BitOr}; use chrono::{NaiveDate, NaiveTime}; use heapless::{Deque, Vec}; +use serde::Serialize; use crate::{parse_str, sentences::*, Error, ParseResult}; @@ -434,7 +435,7 @@ struct SatsPack { max_len: usize, } -#[derive(Clone, PartialEq)] +#[derive(Serialize, Clone, PartialEq)] /// Satellite information pub struct Satellite { pub(crate) gnss_type: GnssType, @@ -696,7 +697,7 @@ define_sentence_type_enum! { /// ### Vendor extensions /// /// - [`SentenceType::RMZ`] - #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] + #[derive( Debug, Serialize, Hash, PartialEq, Eq, Clone, Copy)] #[repr(u32)] #[allow(rustdoc::bare_urls)] pub enum SentenceType { @@ -1179,7 +1180,7 @@ define_sentence_type_enum! { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] +#[derive(Serialize, Copy, Clone, PartialEq, Eq, Debug, Default)] pub struct SentenceMask { mask: u128, } diff --git a/src/sentences/aam.rs b/src/sentences/aam.rs index 5450bb4..8c0d941 100644 --- a/src/sentences/aam.rs +++ b/src/sentences/aam.rs @@ -7,6 +7,7 @@ use nom::{ combinator::opt, number::complete::float, }; +use serde::Serialize; use crate::{parse::NmeaSentence, sentences::utils::array_string, Error, SentenceType}; @@ -30,7 +31,7 @@ use crate::{parse::NmeaSentence, sentences::utils::array_string, Error, Sentence /// Example: $GPAAM,A,A,0.10,N,WPTNME*43 /// WPTNME is the waypoint name. /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct AamData { pub arrival_circle_entered: Option, pub perpendicular_passed: Option, diff --git a/src/sentences/alm.rs b/src/sentences/alm.rs index 1882573..0b06cba 100644 --- a/src/sentences/alm.rs +++ b/src/sentences/alm.rs @@ -7,6 +7,7 @@ use nom::{ combinator::{map_res, opt}, IResult, }; +use serde::Serialize; use crate::{Error, NmeaSentence, SentenceType}; @@ -44,7 +45,7 @@ use super::utils::number; /// 16. Checksum /// /// Fields 5 through 15 are dumped as raw hex. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub struct AlmData { pub total_number_of_messages: Option, pub sentence_number: Option, diff --git a/src/sentences/bod.rs b/src/sentences/bod.rs index 0f21ffe..b8b68e3 100644 --- a/src/sentences/bod.rs +++ b/src/sentences/bod.rs @@ -8,6 +8,7 @@ use nom::{ number::complete::float, sequence::preceded, }; +use serde::Serialize; /// BOD - Bearing - Waypoint to Waypoint /// @@ -18,7 +19,7 @@ use nom::{ /// | | | | | | | /// $--BOD,x.x,T,x.x,M,c--c,c--c*hh /// ``` -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq)] pub struct BodData { pub bearing_true: Option, pub bearing_magnetic: Option, diff --git a/src/sentences/bwc.rs b/src/sentences/bwc.rs index 88c1a0a..3c88e6d 100644 --- a/src/sentences/bwc.rs +++ b/src/sentences/bwc.rs @@ -3,6 +3,7 @@ use chrono::NaiveTime; use nom::{ bytes::complete::is_not, character::complete::char, combinator::opt, number::complete::float, }; +use serde::Serialize; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -20,7 +21,7 @@ use crate::{ /// | | | | | | | | | | | | | | /// $--BWC,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x.x,T,x.x,M,x.x,N,c--c,m,*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct BwcData { pub fix_time: Option, pub latitude: Option, diff --git a/src/sentences/bww.rs b/src/sentences/bww.rs index 4d190e0..bda90d9 100644 --- a/src/sentences/bww.rs +++ b/src/sentences/bww.rs @@ -2,6 +2,7 @@ use arrayvec::ArrayString; use nom::{ bytes::complete::is_not, character::complete::char, combinator::opt, number::complete::float, }; +use serde::Serialize; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -29,7 +30,7 @@ use super::utils::array_string; /// 6. FROM Waypoint ID /// 7. Checksum -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct BwwData { pub true_bearing: Option, pub magnetic_bearing: Option, diff --git a/src/sentences/dbk.rs b/src/sentences/dbk.rs index a02cc65..f238ffc 100644 --- a/src/sentences/dbk.rs +++ b/src/sentences/dbk.rs @@ -5,6 +5,7 @@ use nom::{ sequence::preceded, IResult, }; +use serde::Serialize; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -24,7 +25,7 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// 5: Depth, Fathoms /// 6: F = Fathoms /// 7: Mandatory NMEA checksum -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct DbkData { pub depth_feet: Option, pub depth_meters: Option, diff --git a/src/sentences/faa_mode.rs b/src/sentences/faa_mode.rs index 9b26a05..bdecb49 100644 --- a/src/sentences/faa_mode.rs +++ b/src/sentences/faa_mode.rs @@ -1,9 +1,10 @@ use nom::{character::complete::anychar, combinator::opt, IResult}; +use serde::Serialize; use super::{nom_parse_failure, FixType}; /// for now let's handle only two GPS and GLONASS -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] pub struct FaaModes { sys_state0: FaaMode, sys_state1: Option, @@ -24,7 +25,7 @@ impl From for FixType { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] pub enum FaaMode { /// A - Autonomous mode Autonomous, diff --git a/src/sentences/fix_type.rs b/src/sentences/fix_type.rs index d5ecd21..038dd81 100644 --- a/src/sentences/fix_type.rs +++ b/src/sentences/fix_type.rs @@ -1,5 +1,7 @@ +use serde::Serialize; + /// Fix type -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Serialize, Copy, Clone, PartialEq, Eq, Debug)] pub enum FixType { Invalid, Gps, diff --git a/src/sentences/gbs.rs b/src/sentences/gbs.rs index 1286a64..0e09c81 100644 --- a/src/sentences/gbs.rs +++ b/src/sentences/gbs.rs @@ -1,5 +1,6 @@ use chrono::NaiveTime; use nom::{character::complete::char, combinator::opt, number::complete::float, IResult}; +use serde::Serialize; use crate::{ parse::NmeaSentence, @@ -16,7 +17,7 @@ use crate::{ /// | | | | | | | | | /// $--GBS,hhmmss.ss,x.x,x.x,x.x,x.x,x.x,x.x,x.x*hh /// ``` -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq)] pub struct GbsData { pub time: Option, pub lat_error: Option, diff --git a/src/sentences/gga.rs b/src/sentences/gga.rs index e1e8488..bf5a30c 100644 --- a/src/sentences/gga.rs +++ b/src/sentences/gga.rs @@ -6,6 +6,7 @@ use nom::{ number::complete::float, IResult, }; +use serde::Serialize; use crate::{ parse::NmeaSentence, @@ -26,7 +27,7 @@ use crate::{ /// | | | | | | | | | | | | | | | /// $--GGA,hhmmss.ss,ddmm.mm,a,ddmm.mm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct GgaData { pub fix_time: Option, pub fix_type: Option, diff --git a/src/sentences/gll.rs b/src/sentences/gll.rs index e8db333..23ebd2e 100644 --- a/src/sentences/gll.rs +++ b/src/sentences/gll.rs @@ -4,6 +4,7 @@ use nom::{ combinator::opt, IResult, }; +use serde::Serialize; use super::{faa_mode::parse_faa_mode, nom_parse_failure, FaaMode}; use crate::{ @@ -28,7 +29,7 @@ use crate::{ /// | | | | | | | /// $--GLL,ddmm.mm,a,dddmm.mm,a,hhmmss.ss,a,m*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct GllData { pub latitude: Option, pub longitude: Option, diff --git a/src/sentences/gns.rs b/src/sentences/gns.rs index a0377d5..c79fc90 100644 --- a/src/sentences/gns.rs +++ b/src/sentences/gns.rs @@ -7,6 +7,7 @@ use nom::{ sequence::preceded, IResult, }; +use serde::Serialize; use super::{ faa_mode::parse_faa_modes, @@ -24,7 +25,7 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// | | | | | | | | | | | | | /// $--GNS,hhmmss.ss,ddmm.mm,a,dddmm.mm,a,c--c,xx,x.x,x.x,x.x,x.x,x.x*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct GnsData { pub fix_time: Option, pub lat: Option, @@ -37,7 +38,7 @@ pub struct GnsData { pub nav_status: Option, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] pub enum NavigationStatus { Safe, Caution, diff --git a/src/sentences/gnss_type.rs b/src/sentences/gnss_type.rs index 2cf4b42..303efd1 100644 --- a/src/sentences/gnss_type.rs +++ b/src/sentences/gnss_type.rs @@ -1,6 +1,6 @@ -use core::fmt; - use crate::count_tts; +use core::fmt; +use serde::Serialize; macro_rules! define_enum_with_count { ( @@ -11,7 +11,7 @@ macro_rules! define_enum_with_count { ),* $(,)* } ) => { $(#[$outer])* - #[derive(PartialEq, Debug, Hash, Eq, Clone, Copy)] + #[derive(Serialize,PartialEq, Debug, Hash, Eq, Clone, Copy)] #[repr(u8)] pub enum $Name { $($Variant),* diff --git a/src/sentences/gsa.rs b/src/sentences/gsa.rs index 6572d26..84bb144 100644 --- a/src/sentences/gsa.rs +++ b/src/sentences/gsa.rs @@ -9,16 +9,17 @@ use nom::{ sequence::terminated, Err, IResult, InputLength, Parser, }; +use serde::Serialize; use crate::{parse::NmeaSentence, sentences::utils::number, Error, SentenceType}; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum GsaMode1 { Manual, Automatic, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum GsaMode2 { NoFix, Fix2D, @@ -34,7 +35,7 @@ pub enum GsaMode2 { /// | | | | | | | | /// $--GSA,a,a,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x.x,x.x,x.x*hh /// ``` -#[derive(Debug, Clone, PartialEq)] +#[derive(Serialize, Debug, Clone, PartialEq)] pub struct GsaData { pub mode1: GsaMode1, pub mode2: GsaMode2, diff --git a/src/sentences/gsv.rs b/src/sentences/gsv.rs index d889914..017cff9 100644 --- a/src/sentences/gsv.rs +++ b/src/sentences/gsv.rs @@ -4,6 +4,7 @@ use nom::{ combinator::{cond, opt, rest_len}, IResult, }; +use serde::Serialize; use crate::{ parse::NmeaSentence, @@ -20,7 +21,7 @@ use crate::{ /// | | | | | | | | /// $--GSV,x,x,x,x,x,x,x,...*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct GsvData { pub gnss_type: GnssType, pub number_of_sentences: u16, diff --git a/src/sentences/hdt.rs b/src/sentences/hdt.rs index c6653b3..58ee1ae 100644 --- a/src/sentences/hdt.rs +++ b/src/sentences/hdt.rs @@ -4,6 +4,7 @@ use nom::{ combinator::{map_res, opt}, IResult, }; +use serde::Serialize; use super::utils::parse_float_num; use crate::{Error, NmeaSentence, SentenceType}; @@ -20,7 +21,7 @@ use crate::{Error, NmeaSentence, SentenceType}; /// 1. Heading, degrees True /// 2. T = True /// 3. Checksum -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct HdtData { /// Heading, degrees True pub heading: Option, diff --git a/src/sentences/mda.rs b/src/sentences/mda.rs index 14ab6e3..2d798ed 100644 --- a/src/sentences/mda.rs +++ b/src/sentences/mda.rs @@ -1,4 +1,5 @@ use nom::{character::complete::char, combinator::opt, number::complete::float, IResult}; +use serde::Serialize; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -11,7 +12,7 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// | | | | | | | | | | | | | | | | | | | | | /// $--MDA,n.nn,I,n.nnn,B,n.n,C,n.C,n.n,n,n.n,C,n.n,T,n.n,M,n.n,N,n.n,M*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct MdaData { /// Pressure in inches of mercury pub pressure_in_hg: Option, diff --git a/src/sentences/mod.rs b/src/sentences/mod.rs index dc185da..7f4285e 100644 --- a/src/sentences/mod.rs +++ b/src/sentences/mod.rs @@ -30,7 +30,7 @@ pub mod faa_mode; pub mod fix_type; pub mod gnss_type; -pub(crate) use { +pub use { aam::{parse_aam, AamData}, alm::{parse_alm, AlmData}, bod::{parse_bod, BodData}, diff --git a/src/sentences/mtw.rs b/src/sentences/mtw.rs index 771c1a5..a388a91 100644 --- a/src/sentences/mtw.rs +++ b/src/sentences/mtw.rs @@ -5,6 +5,7 @@ use nom::{ sequence::preceded, IResult, }; +use serde::Serialize; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -20,12 +21,12 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// 1: Temperature, degrees /// 2: Unit of Measurement, (only) Celsius /// 3: Mandatory NMEA checksum -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct MtwData { pub temperature: Option, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum MtwUnit { Celsius, } diff --git a/src/sentences/mwv.rs b/src/sentences/mwv.rs index cb1f278..5fa5fd8 100644 --- a/src/sentences/mwv.rs +++ b/src/sentences/mwv.rs @@ -5,6 +5,7 @@ use nom::{ sequence::preceded, IResult, }; +use serde::Serialize; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -17,7 +18,7 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// | | | | | /// $--MWV,x.x,a,x.x,a*hh /// ``` -#[derive(Debug, PartialEq)] +#[derive(Serialize, Debug, PartialEq)] pub struct MwvData { pub wind_direction: Option, pub reference: Option, @@ -26,13 +27,13 @@ pub struct MwvData { pub data_valid: bool, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum MwvReference { Relative, Theoretical, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum MwvWindSpeedUnits { KilometersPerHour, MetersPerSecond, diff --git a/src/sentences/rmc.rs b/src/sentences/rmc.rs index f71bb47..95fb24c 100644 --- a/src/sentences/rmc.rs +++ b/src/sentences/rmc.rs @@ -5,6 +5,7 @@ use nom::{ number::complete::float, IResult, }; +use serde::Serialize; use crate::{ parse::NmeaSentence, @@ -14,14 +15,14 @@ use crate::{ use super::{faa_mode::parse_faa_mode, utils::parse_magnetic_variation, FaaMode}; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum RmcStatusOfFix { Autonomous, Differential, Invalid, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum RmcNavigationStatus { Autonomous, Differential, @@ -72,7 +73,7 @@ pub enum RmcNavigationStatus { /// 13. Nav Status (NMEA 4.1 and later) /// `A` = autonomous, `D` = differential, `E` = Estimated, /// `M` = Manual input mode, `N` = not valid, `S` = Simulator, `V` = Valid -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq)] pub struct RmcData { pub fix_time: Option, pub fix_date: Option, diff --git a/src/sentences/rmz.rs b/src/sentences/rmz.rs index 8173ec8..bfc914d 100644 --- a/src/sentences/rmz.rs +++ b/src/sentences/rmz.rs @@ -2,11 +2,12 @@ use nom::{ character::complete::{char, one_of}, IResult, }; +use serde::Serialize; use crate::sentences::utils::number; use crate::{parse::NmeaSentence, Error, SentenceType}; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum PgrmzFixType { NoFix, TwoDimensional, @@ -29,7 +30,7 @@ pub enum PgrmzFixType { /// 4. Checksum /// /// Example: `$PGRMZ,2282,f,3*21` -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub struct PgrmzData { /// Current altitude in feet pub altitude: u32, diff --git a/src/sentences/txt.rs b/src/sentences/txt.rs index 9d30094..db2e38d 100644 --- a/src/sentences/txt.rs +++ b/src/sentences/txt.rs @@ -1,5 +1,6 @@ use arrayvec::ArrayString; use nom::{bytes::complete::take_while, character::complete::char, IResult}; +use serde::Serialize; use super::utils::number; use crate::{ @@ -63,7 +64,7 @@ fn do_parse_txt(i: &str) -> IResult<&str, TxtData0<'_>> { } /// TXT - Text -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] pub struct TxtData { pub count: u8, pub seq: u8, diff --git a/src/sentences/vhw.rs b/src/sentences/vhw.rs index c0232aa..7a15717 100644 --- a/src/sentences/vhw.rs +++ b/src/sentences/vhw.rs @@ -4,6 +4,7 @@ use nom::{ combinator::{map_res, opt}, IResult, }; +use serde::Serialize; use crate::{Error, NmeaSentence, SentenceType}; @@ -31,7 +32,7 @@ use super::utils::parse_float_num; /// Note that this implementation follows the documentation published by `gpsd`, but the GLOBALSAT documentation may have conflicting definitions. /// > [[GLOBALSAT](https://gpsd.gitlab.io/gpsd/NMEA.html#GLOBALSAT)] describes a different format in which the first three fields are water-temperature measurements. /// > It’s not clear which is correct. -#[derive(Clone, PartialEq, Debug)] +#[derive(Serialize, Clone, PartialEq, Debug)] pub struct VhwData { /// Heading degrees, True pub heading_true: Option, diff --git a/src/sentences/vtg.rs b/src/sentences/vtg.rs index 3077a68..de21ffc 100644 --- a/src/sentences/vtg.rs +++ b/src/sentences/vtg.rs @@ -1,4 +1,5 @@ use nom::{character::complete::char, combinator::opt, number::complete::float, IResult}; +use serde::Serialize; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -17,7 +18,7 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// ```text /// $--VTG,x.x,T,x.x,M,x.x,N,x.x,K,m*hh /// ``` -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Serialize, Debug, Clone, Copy, PartialEq)] pub struct VtgData { pub true_course: Option, pub speed_over_ground: Option, diff --git a/src/sentences/zda.rs b/src/sentences/zda.rs index c6c719a..fdcf2d9 100644 --- a/src/sentences/zda.rs +++ b/src/sentences/zda.rs @@ -5,6 +5,7 @@ use nom::{ combinator::{map_res, opt}, IResult, }; +use serde::Serialize; use crate::{parse::NmeaSentence, sentences::utils::parse_hms, Error, SentenceType}; @@ -27,7 +28,7 @@ use super::utils::{parse_num, parse_number_in_range}; /// 5. Local zone description, 00 to +- 13 hours /// 6. Local zone minutes description, 00 to 59, apply same sign as local hours /// 7. Checksum -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Debug, Clone, PartialEq, Eq)] pub struct ZdaData { pub utc_time: Option, pub day: Option, diff --git a/src/sentences/zfo.rs b/src/sentences/zfo.rs index f50ecb5..74741e7 100644 --- a/src/sentences/zfo.rs +++ b/src/sentences/zfo.rs @@ -1,6 +1,7 @@ use arrayvec::ArrayString; use chrono::{Duration, NaiveTime}; use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; +use serde::Serialize; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -19,9 +20,11 @@ use crate::{ /// 2. Elapsed Time /// 3. Origin Waypoint ID /// 4. Checksum -#[derive(Debug, PartialEq)] +#[serde_with::serde_as] +#[derive(Serialize, Debug, PartialEq)] pub struct ZfoData { pub fix_time: Option, + #[serde_as(as = "Option>")] pub fix_duration: Option, pub waypoint_id: Option>, } diff --git a/src/sentences/ztg.rs b/src/sentences/ztg.rs index 4147c19..ae3345d 100644 --- a/src/sentences/ztg.rs +++ b/src/sentences/ztg.rs @@ -1,6 +1,7 @@ use arrayvec::ArrayString; use chrono::{Duration, NaiveTime}; use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; +use serde::Serialize; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -21,9 +22,11 @@ use super::utils::array_string; /// 2. Time Remaining /// 3. Destination Waypoint ID /// 4. Checksum -#[derive(Debug, PartialEq)] +#[serde_with::serde_as] +#[derive(Serialize, Debug, PartialEq)] pub struct ZtgData { pub fix_time: Option, + #[serde_as(as = "Option>")] pub fix_duration: Option, pub waypoint_id: Option>, } From abde8392544b629f05412cf37cc1579047be1e9f Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Mon, 12 Jun 2023 23:33:36 +0200 Subject: [PATCH 02/14] feat!: add deserialization, add serde feature --- src/parse.rs | 6 ++- src/parser.rs | 75 ++++++++++++++++++++++++++++++++++++-- src/sentences/aam.rs | 7 +++- src/sentences/alm.rs | 7 +++- src/sentences/bod.rs | 7 +++- src/sentences/bwc.rs | 7 +++- src/sentences/bww.rs | 7 +++- src/sentences/dbk.rs | 7 +++- src/sentences/faa_mode.rs | 10 +++-- src/sentences/fix_type.rs | 6 ++- src/sentences/gbs.rs | 7 +++- src/sentences/gga.rs | 7 +++- src/sentences/gll.rs | 8 +++- src/sentences/gns.rs | 10 +++-- src/sentences/gnss_type.rs | 7 +++- src/sentences/gsa.rs | 13 +++++-- src/sentences/gsv.rs | 7 +++- src/sentences/hdt.rs | 7 +++- src/sentences/mda.rs | 7 +++- src/sentences/mtw.rs | 10 +++-- src/sentences/mwv.rs | 13 +++++-- src/sentences/rmc.rs | 13 +++++-- src/sentences/rmz.rs | 10 +++-- src/sentences/txt.rs | 7 +++- src/sentences/vhw.rs | 7 +++- src/sentences/vtg.rs | 7 +++- src/sentences/zda.rs | 7 +++- src/sentences/zfo.rs | 11 ++++-- src/sentences/ztg.rs | 11 ++++-- 29 files changed, 234 insertions(+), 74 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index 6d3f95b..c6cb55f 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -7,7 +7,9 @@ use nom::{ sequence::preceded, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{sentences::*, Error, SentenceType}; @@ -34,7 +36,7 @@ pub const SENTENCE_MAX_LEN: usize = 102; pub const TEXT_PARAMETER_MAX_LEN: usize = 64; /// A known and parsable Nmea sentence type. -#[derive(Serialize)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct NmeaSentence<'a> { pub talker_id: &'a str, pub message_id: SentenceType, diff --git a/src/parser.rs b/src/parser.rs index a49a059..164bfdc 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -4,7 +4,11 @@ use core::{fmt, mem, ops::BitOr}; use chrono::{NaiveDate, NaiveTime}; use heapless::{Deque, Vec}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{de::Visitor, ser::SerializeSeq, Deserialize, Serialize}; +#[cfg(feature = "serde")] +use std::marker::PhantomData; use crate::{parse_str, sentences::*, Error, ParseResult}; @@ -24,6 +28,7 @@ use crate::{parse_str, sentences::*, Error, ParseResult}; /// nmea.parse(gga).unwrap(); /// println!("{}", nmea); /// ``` +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Default)] pub struct Nmea { pub fix_time: Option, @@ -423,6 +428,7 @@ impl fmt::Display for Nmea { } } +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Default)] struct SatsPack { /// max number of visible GNSS satellites per hemisphere, assuming global coverage @@ -431,11 +437,70 @@ struct SatsPack { /// BeiDou: 12 + 3 IGSO + 3 GEO /// Galileo: 12 /// => 58 total Satellites => max 15 rows of data + #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_deque"))] + #[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_deque"))] data: Deque, 4>, 15>, max_len: usize, } -#[derive(Serialize, Clone, PartialEq)] +#[cfg(feature = "serde")] +fn serialize_deque(v: &Deque, 4>, 15>, s: S) -> Result +where + S: serde::Serializer, +{ + let mut seq = s.serialize_seq(Some(15))?; + for e in v.iter() { + seq.serialize_element(e)?; + } + seq.end() +} + +#[cfg(feature = "serde")] +struct DequeVisitor { + marker: PhantomData Deque, 4>, 15>>, +} + +#[cfg(feature = "serde")] +impl DequeVisitor { + fn new() -> Self { + Self { + marker: PhantomData, + } + } +} + +#[cfg(feature = "serde")] +impl<'de> Visitor<'de> for DequeVisitor { + type Value = Deque, 4>, 15>; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("deque") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + let mut deq: Deque, 4>, 15> = Deque::new(); + + while let Some(v) = seq.next_element()? { + deq.push_back(v).expect("Cannot deserialize"); + } + + Ok(deq) + } +} + +#[cfg(feature = "serde")] +fn deserialize_deque<'de, D>(d: D) -> Result, 4>, 15>, D::Error> +where + D: serde::Deserializer<'de>, +{ + d.deserialize_seq(DequeVisitor::new()) +} + +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, PartialEq)] /// Satellite information pub struct Satellite { pub(crate) gnss_type: GnssType, @@ -697,7 +762,8 @@ define_sentence_type_enum! { /// ### Vendor extensions /// /// - [`SentenceType::RMZ`] - #[derive( Debug, Serialize, Hash, PartialEq, Eq, Clone, Copy)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[repr(u32)] #[allow(rustdoc::bare_urls)] pub enum SentenceType { @@ -1180,7 +1246,8 @@ define_sentence_type_enum! { } } -#[derive(Serialize, Copy, Clone, PartialEq, Eq, Debug, Default)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] pub struct SentenceMask { mask: u128, } diff --git a/src/sentences/aam.rs b/src/sentences/aam.rs index 8c0d941..2818c01 100644 --- a/src/sentences/aam.rs +++ b/src/sentences/aam.rs @@ -7,7 +7,9 @@ use nom::{ combinator::opt, number::complete::float, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, sentences::utils::array_string, Error, SentenceType}; @@ -31,7 +33,8 @@ use crate::{parse::NmeaSentence, sentences::utils::array_string, Error, Sentence /// Example: $GPAAM,A,A,0.10,N,WPTNME*43 /// WPTNME is the waypoint name. /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct AamData { pub arrival_circle_entered: Option, pub perpendicular_passed: Option, diff --git a/src/sentences/alm.rs b/src/sentences/alm.rs index 0b06cba..eee6088 100644 --- a/src/sentences/alm.rs +++ b/src/sentences/alm.rs @@ -7,7 +7,9 @@ use nom::{ combinator::{map_res, opt}, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{Error, NmeaSentence, SentenceType}; @@ -45,7 +47,8 @@ use super::utils::number; /// 16. Checksum /// /// Fields 5 through 15 are dumped as raw hex. -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AlmData { pub total_number_of_messages: Option, pub sentence_number: Option, diff --git a/src/sentences/bod.rs b/src/sentences/bod.rs index b8b68e3..8849efd 100644 --- a/src/sentences/bod.rs +++ b/src/sentences/bod.rs @@ -8,7 +8,9 @@ use nom::{ number::complete::float, sequence::preceded, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; /// BOD - Bearing - Waypoint to Waypoint /// @@ -19,7 +21,8 @@ use serde::Serialize; /// | | | | | | | /// $--BOD,x.x,T,x.x,M,c--c,c--c*hh /// ``` -#[derive(Serialize, Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct BodData { pub bearing_true: Option, pub bearing_magnetic: Option, diff --git a/src/sentences/bwc.rs b/src/sentences/bwc.rs index 3c88e6d..13f0a1c 100644 --- a/src/sentences/bwc.rs +++ b/src/sentences/bwc.rs @@ -3,7 +3,9 @@ use chrono::NaiveTime; use nom::{ bytes::complete::is_not, character::complete::char, combinator::opt, number::complete::float, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -21,7 +23,8 @@ use crate::{ /// | | | | | | | | | | | | | | /// $--BWC,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x.x,T,x.x,M,x.x,N,c--c,m,*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct BwcData { pub fix_time: Option, pub latitude: Option, diff --git a/src/sentences/bww.rs b/src/sentences/bww.rs index bda90d9..62d15e2 100644 --- a/src/sentences/bww.rs +++ b/src/sentences/bww.rs @@ -2,7 +2,9 @@ use arrayvec::ArrayString; use nom::{ bytes::complete::is_not, character::complete::char, combinator::opt, number::complete::float, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -30,7 +32,8 @@ use super::utils::array_string; /// 6. FROM Waypoint ID /// 7. Checksum -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct BwwData { pub true_bearing: Option, pub magnetic_bearing: Option, diff --git a/src/sentences/dbk.rs b/src/sentences/dbk.rs index f238ffc..2089aaf 100644 --- a/src/sentences/dbk.rs +++ b/src/sentences/dbk.rs @@ -5,7 +5,9 @@ use nom::{ sequence::preceded, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Serialize, Deserialize}; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -25,7 +27,8 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// 5: Depth, Fathoms /// 6: F = Fathoms /// 7: Mandatory NMEA checksum -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct DbkData { pub depth_feet: Option, pub depth_meters: Option, diff --git a/src/sentences/faa_mode.rs b/src/sentences/faa_mode.rs index bdecb49..90dcf4c 100644 --- a/src/sentences/faa_mode.rs +++ b/src/sentences/faa_mode.rs @@ -1,10 +1,13 @@ use nom::{character::complete::anychar, combinator::opt, IResult}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use super::{nom_parse_failure, FixType}; /// for now let's handle only two GPS and GLONASS -#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct FaaModes { sys_state0: FaaMode, sys_state1: Option, @@ -25,7 +28,8 @@ impl From for FixType { } } -#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum FaaMode { /// A - Autonomous mode Autonomous, diff --git a/src/sentences/fix_type.rs b/src/sentences/fix_type.rs index 038dd81..a29f7b4 100644 --- a/src/sentences/fix_type.rs +++ b/src/sentences/fix_type.rs @@ -1,7 +1,9 @@ -use serde::Serialize; +#[cfg(feature = "serde")] +use serde::{Serialize, Deserialize}; /// Fix type -#[derive(Serialize, Copy, Clone, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum FixType { Invalid, Gps, diff --git a/src/sentences/gbs.rs b/src/sentences/gbs.rs index 0e09c81..8bd2dd0 100644 --- a/src/sentences/gbs.rs +++ b/src/sentences/gbs.rs @@ -1,6 +1,8 @@ use chrono::NaiveTime; use nom::{character::complete::char, combinator::opt, number::complete::float, IResult}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::NmeaSentence, @@ -17,7 +19,8 @@ use crate::{ /// | | | | | | | | | /// $--GBS,hhmmss.ss,x.x,x.x,x.x,x.x,x.x,x.x,x.x*hh /// ``` -#[derive(Serialize, Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct GbsData { pub time: Option, pub lat_error: Option, diff --git a/src/sentences/gga.rs b/src/sentences/gga.rs index bf5a30c..0db59b7 100644 --- a/src/sentences/gga.rs +++ b/src/sentences/gga.rs @@ -6,7 +6,9 @@ use nom::{ number::complete::float, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::NmeaSentence, @@ -27,7 +29,8 @@ use crate::{ /// | | | | | | | | | | | | | | | /// $--GGA,hhmmss.ss,ddmm.mm,a,ddmm.mm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct GgaData { pub fix_time: Option, pub fix_type: Option, diff --git a/src/sentences/gll.rs b/src/sentences/gll.rs index 23ebd2e..52077d6 100644 --- a/src/sentences/gll.rs +++ b/src/sentences/gll.rs @@ -4,7 +4,9 @@ use nom::{ combinator::opt, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use super::{faa_mode::parse_faa_mode, nom_parse_failure, FaaMode}; use crate::{ @@ -29,7 +31,9 @@ use crate::{ /// | | | | | | | /// $--GLL,ddmm.mm,a,dddmm.mm,a,hhmmss.ss,a,m*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] + +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct GllData { pub latitude: Option, pub longitude: Option, diff --git a/src/sentences/gns.rs b/src/sentences/gns.rs index c79fc90..563fd25 100644 --- a/src/sentences/gns.rs +++ b/src/sentences/gns.rs @@ -7,7 +7,9 @@ use nom::{ sequence::preceded, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use super::{ faa_mode::parse_faa_modes, @@ -25,7 +27,8 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// | | | | | | | | | | | | | /// $--GNS,hhmmss.ss,ddmm.mm,a,dddmm.mm,a,c--c,xx,x.x,x.x,x.x,x.x,x.x*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct GnsData { pub fix_time: Option, pub lat: Option, @@ -38,7 +41,8 @@ pub struct GnsData { pub nav_status: Option, } -#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum NavigationStatus { Safe, Caution, diff --git a/src/sentences/gnss_type.rs b/src/sentences/gnss_type.rs index 303efd1..d6ab56b 100644 --- a/src/sentences/gnss_type.rs +++ b/src/sentences/gnss_type.rs @@ -1,6 +1,8 @@ use crate::count_tts; use core::fmt; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; macro_rules! define_enum_with_count { ( @@ -11,7 +13,8 @@ macro_rules! define_enum_with_count { ),* $(,)* } ) => { $(#[$outer])* - #[derive(Serialize,PartialEq, Debug, Hash, Eq, Clone, Copy)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[derive(PartialEq, Debug, Hash, Eq, Clone, Copy)] #[repr(u8)] pub enum $Name { $($Variant),* diff --git a/src/sentences/gsa.rs b/src/sentences/gsa.rs index 84bb144..ba6805e 100644 --- a/src/sentences/gsa.rs +++ b/src/sentences/gsa.rs @@ -9,17 +9,21 @@ use nom::{ sequence::terminated, Err, IResult, InputLength, Parser, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, sentences::utils::number, Error, SentenceType}; -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GsaMode1 { Manual, Automatic, } -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GsaMode2 { NoFix, Fix2D, @@ -35,7 +39,8 @@ pub enum GsaMode2 { /// | | | | | | | | /// $--GSA,a,a,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x.x,x.x,x.x*hh /// ``` -#[derive(Serialize, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, PartialEq)] pub struct GsaData { pub mode1: GsaMode1, pub mode2: GsaMode2, diff --git a/src/sentences/gsv.rs b/src/sentences/gsv.rs index 017cff9..1c4dd16 100644 --- a/src/sentences/gsv.rs +++ b/src/sentences/gsv.rs @@ -4,7 +4,9 @@ use nom::{ combinator::{cond, opt, rest_len}, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::NmeaSentence, @@ -21,7 +23,8 @@ use crate::{ /// | | | | | | | | /// $--GSV,x,x,x,x,x,x,x,...*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct GsvData { pub gnss_type: GnssType, pub number_of_sentences: u16, diff --git a/src/sentences/hdt.rs b/src/sentences/hdt.rs index 58ee1ae..e3bcd95 100644 --- a/src/sentences/hdt.rs +++ b/src/sentences/hdt.rs @@ -4,7 +4,9 @@ use nom::{ combinator::{map_res, opt}, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use super::utils::parse_float_num; use crate::{Error, NmeaSentence, SentenceType}; @@ -21,7 +23,8 @@ use crate::{Error, NmeaSentence, SentenceType}; /// 1. Heading, degrees True /// 2. T = True /// 3. Checksum -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct HdtData { /// Heading, degrees True pub heading: Option, diff --git a/src/sentences/mda.rs b/src/sentences/mda.rs index 2d798ed..48a454b 100644 --- a/src/sentences/mda.rs +++ b/src/sentences/mda.rs @@ -1,5 +1,7 @@ use nom::{character::complete::char, combinator::opt, number::complete::float, IResult}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -12,7 +14,8 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// | | | | | | | | | | | | | | | | | | | | | /// $--MDA,n.nn,I,n.nnn,B,n.n,C,n.C,n.n,n,n.n,C,n.n,T,n.n,M,n.n,N,n.n,M*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct MdaData { /// Pressure in inches of mercury pub pressure_in_hg: Option, diff --git a/src/sentences/mtw.rs b/src/sentences/mtw.rs index a388a91..c1d8484 100644 --- a/src/sentences/mtw.rs +++ b/src/sentences/mtw.rs @@ -5,7 +5,9 @@ use nom::{ sequence::preceded, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -21,12 +23,14 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// 1: Temperature, degrees /// 2: Unit of Measurement, (only) Celsius /// 3: Mandatory NMEA checksum -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct MtwData { pub temperature: Option, } -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MtwUnit { Celsius, } diff --git a/src/sentences/mwv.rs b/src/sentences/mwv.rs index 5fa5fd8..dd7cc5e 100644 --- a/src/sentences/mwv.rs +++ b/src/sentences/mwv.rs @@ -5,7 +5,9 @@ use nom::{ sequence::preceded, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -18,7 +20,8 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// | | | | | /// $--MWV,x.x,a,x.x,a*hh /// ``` -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct MwvData { pub wind_direction: Option, pub reference: Option, @@ -27,13 +30,15 @@ pub struct MwvData { pub data_valid: bool, } -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MwvReference { Relative, Theoretical, } -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MwvWindSpeedUnits { KilometersPerHour, MetersPerSecond, diff --git a/src/sentences/rmc.rs b/src/sentences/rmc.rs index 95fb24c..7d60ef7 100644 --- a/src/sentences/rmc.rs +++ b/src/sentences/rmc.rs @@ -5,7 +5,9 @@ use nom::{ number::complete::float, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::NmeaSentence, @@ -15,14 +17,16 @@ use crate::{ use super::{faa_mode::parse_faa_mode, utils::parse_magnetic_variation, FaaMode}; -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RmcStatusOfFix { Autonomous, Differential, Invalid, } -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RmcNavigationStatus { Autonomous, Differential, @@ -73,7 +77,8 @@ pub enum RmcNavigationStatus { /// 13. Nav Status (NMEA 4.1 and later) /// `A` = autonomous, `D` = differential, `E` = Estimated, /// `M` = Manual input mode, `N` = not valid, `S` = Simulator, `V` = Valid -#[derive(Serialize, Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct RmcData { pub fix_time: Option, pub fix_date: Option, diff --git a/src/sentences/rmz.rs b/src/sentences/rmz.rs index bfc914d..8064bda 100644 --- a/src/sentences/rmz.rs +++ b/src/sentences/rmz.rs @@ -2,12 +2,15 @@ use nom::{ character::complete::{char, one_of}, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::sentences::utils::number; use crate::{parse::NmeaSentence, Error, SentenceType}; -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PgrmzFixType { NoFix, TwoDimensional, @@ -30,7 +33,8 @@ pub enum PgrmzFixType { /// 4. Checksum /// /// Example: `$PGRMZ,2282,f,3*21` -#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PgrmzData { /// Current altitude in feet pub altitude: u32, diff --git a/src/sentences/txt.rs b/src/sentences/txt.rs index db2e38d..6b2d936 100644 --- a/src/sentences/txt.rs +++ b/src/sentences/txt.rs @@ -1,6 +1,8 @@ use arrayvec::ArrayString; use nom::{bytes::complete::take_while, character::complete::char, IResult}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use super::utils::number; use crate::{ @@ -64,7 +66,8 @@ fn do_parse_txt(i: &str) -> IResult<&str, TxtData0<'_>> { } /// TXT - Text -#[derive(Serialize, Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct TxtData { pub count: u8, pub seq: u8, diff --git a/src/sentences/vhw.rs b/src/sentences/vhw.rs index 7a15717..863ebf2 100644 --- a/src/sentences/vhw.rs +++ b/src/sentences/vhw.rs @@ -4,7 +4,9 @@ use nom::{ combinator::{map_res, opt}, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{Error, NmeaSentence, SentenceType}; @@ -32,7 +34,8 @@ use super::utils::parse_float_num; /// Note that this implementation follows the documentation published by `gpsd`, but the GLOBALSAT documentation may have conflicting definitions. /// > [[GLOBALSAT](https://gpsd.gitlab.io/gpsd/NMEA.html#GLOBALSAT)] describes a different format in which the first three fields are water-temperature measurements. /// > It’s not clear which is correct. -#[derive(Serialize, Clone, PartialEq, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, PartialEq, Debug)] pub struct VhwData { /// Heading degrees, True pub heading_true: Option, diff --git a/src/sentences/vtg.rs b/src/sentences/vtg.rs index de21ffc..b60f02c 100644 --- a/src/sentences/vtg.rs +++ b/src/sentences/vtg.rs @@ -1,5 +1,7 @@ use nom::{character::complete::char, combinator::opt, number::complete::float, IResult}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, Error, SentenceType}; @@ -18,7 +20,8 @@ use crate::{parse::NmeaSentence, Error, SentenceType}; /// ```text /// $--VTG,x.x,T,x.x,M,x.x,N,x.x,K,m*hh /// ``` -#[derive(Serialize, Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct VtgData { pub true_course: Option, pub speed_over_ground: Option, diff --git a/src/sentences/zda.rs b/src/sentences/zda.rs index fdcf2d9..aa2c69d 100644 --- a/src/sentences/zda.rs +++ b/src/sentences/zda.rs @@ -5,7 +5,9 @@ use nom::{ combinator::{map_res, opt}, IResult, }; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{parse::NmeaSentence, sentences::utils::parse_hms, Error, SentenceType}; @@ -28,7 +30,8 @@ use super::utils::{parse_num, parse_number_in_range}; /// 5. Local zone description, 00 to +- 13 hours /// 6. Local zone minutes description, 00 to 59, apply same sign as local hours /// 7. Checksum -#[derive(Serialize, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ZdaData { pub utc_time: Option, pub day: Option, diff --git a/src/sentences/zfo.rs b/src/sentences/zfo.rs index 74741e7..a41f16a 100644 --- a/src/sentences/zfo.rs +++ b/src/sentences/zfo.rs @@ -1,7 +1,9 @@ use arrayvec::ArrayString; use chrono::{Duration, NaiveTime}; use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -20,11 +22,12 @@ use crate::{ /// 2. Elapsed Time /// 3. Origin Waypoint ID /// 4. Checksum -#[serde_with::serde_as] -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", serde_with::serde_as)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct ZfoData { pub fix_time: Option, - #[serde_as(as = "Option>")] + #[cfg_attr(feature = "serde", serde_as(as = "Option>"))] pub fix_duration: Option, pub waypoint_id: Option>, } diff --git a/src/sentences/ztg.rs b/src/sentences/ztg.rs index ae3345d..c2113ee 100644 --- a/src/sentences/ztg.rs +++ b/src/sentences/ztg.rs @@ -1,7 +1,9 @@ use arrayvec::ArrayString; use chrono::{Duration, NaiveTime}; use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; -use serde::Serialize; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -22,11 +24,12 @@ use super::utils::array_string; /// 2. Time Remaining /// 3. Destination Waypoint ID /// 4. Checksum -#[serde_with::serde_as] -#[derive(Serialize, Debug, PartialEq)] +#[cfg_attr(feature = "serde", serde_with::serde_as)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, PartialEq)] pub struct ZtgData { pub fix_time: Option, - #[serde_as(as = "Option>")] + #[cfg_attr(feature = "serde", serde_as(as = "Option>"))] pub fix_duration: Option, pub waypoint_id: Option>, } From 089ace4b49d8a1e51968f9aa48b87939c9562bb7 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Tue, 13 Jun 2023 00:12:24 +0200 Subject: [PATCH 03/14] fix: use workaround for serde_as behind optional feature --- src/sentences/zfo.rs | 6 ++++-- src/sentences/ztg.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sentences/zfo.rs b/src/sentences/zfo.rs index a41f16a..1049dd3 100644 --- a/src/sentences/zfo.rs +++ b/src/sentences/zfo.rs @@ -5,6 +5,9 @@ use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "serde")] +use serde_with::{As}; + use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, sentences::utils::{array_string, parse_duration_hms, parse_hms}, @@ -22,12 +25,11 @@ use crate::{ /// 2. Elapsed Time /// 3. Origin Waypoint ID /// 4. Checksum -#[cfg_attr(feature = "serde", serde_with::serde_as)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, PartialEq)] pub struct ZfoData { pub fix_time: Option, - #[cfg_attr(feature = "serde", serde_as(as = "Option>"))] + #[cfg_attr(feature = "serde", serde(with = "As::>>"))] pub fix_duration: Option, pub waypoint_id: Option>, } diff --git a/src/sentences/ztg.rs b/src/sentences/ztg.rs index c2113ee..b76e1a4 100644 --- a/src/sentences/ztg.rs +++ b/src/sentences/ztg.rs @@ -5,6 +5,9 @@ use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "serde")] +use serde_with::As; + use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, sentences::utils::{parse_duration_hms, parse_hms}, @@ -24,12 +27,11 @@ use super::utils::array_string; /// 2. Time Remaining /// 3. Destination Waypoint ID /// 4. Checksum -#[cfg_attr(feature = "serde", serde_with::serde_as)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, PartialEq)] pub struct ZtgData { pub fix_time: Option, - #[cfg_attr(feature = "serde", serde_as(as = "Option>"))] + #[cfg_attr(feature = "serde", serde(with = "As::>>"))] pub fix_duration: Option, pub waypoint_id: Option>, } From 2ff00d3d88429b619f59561bbd767656cb611b2f Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Tue, 13 Jun 2023 00:13:14 +0200 Subject: [PATCH 04/14] chore: activate optional dependencies only by features --- Cargo.toml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9edaaf5..4125531 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,16 +26,16 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -arrayvec = { version = "0.7.2", default-features = false, features = ["serde"]} -chrono = { version = "0.4.19", default-features = false, features = ["serde"] } -heapless = { version ="0.7.15", features = ["serde"]} +arrayvec = { version = "0.7.2", default-features = false} +chrono = { version = "0.4.19", default-features = false } +heapless = { version ="0.7.15"} nom = { version = "7.1.1", default-features = false } # we include num-traits only when `std` is not enabled # because of `fract()` and `trunc()` methods num-traits = { version = "0.2", default-features = false } -serde = { version = "1.0.163", features = ["derive"], default-features = false } -serde_with = { version = "3.0.0", default-features = false, features = ["macros", "chrono"] } +serde = { version = "1.0.163", default-features = false, optional = true } +serde_with = { version = "3.0.0", default-features = false, optional = true } [dev-dependencies] approx = "0.5.1" @@ -47,6 +47,14 @@ criterion = "0.4" [features] default = ["std"] std = ["nom/std", "chrono/std", "arrayvec/std"] +serde = [ + "serde/derive", + "serde_with/macros", + "serde_with/chrono_0_4", + "heapless/serde", + "chrono/serde", + "arrayvec/serde" +] [[bench]] name = "nom_parsing" From 62eb5c11e702a92861affda80804859ce4303126 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Wed, 5 Jul 2023 16:00:16 +0200 Subject: [PATCH 05/14] style: make cargo-fmt happy --- src/sentences/fix_type.rs | 2 +- src/sentences/zfo.rs | 7 +++++-- src/sentences/ztg.rs | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sentences/fix_type.rs b/src/sentences/fix_type.rs index a29f7b4..e431493 100644 --- a/src/sentences/fix_type.rs +++ b/src/sentences/fix_type.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// Fix type #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/src/sentences/zfo.rs b/src/sentences/zfo.rs index 1049dd3..9985142 100644 --- a/src/sentences/zfo.rs +++ b/src/sentences/zfo.rs @@ -6,7 +6,7 @@ use nom::{bytes::complete::is_not, character::complete::char, combinator::opt}; use serde::{Deserialize, Serialize}; #[cfg(feature = "serde")] -use serde_with::{As}; +use serde_with::As; use crate::{ parse::{NmeaSentence, TEXT_PARAMETER_MAX_LEN}, @@ -29,7 +29,10 @@ use crate::{ #[derive(Debug, PartialEq)] pub struct ZfoData { pub fix_time: Option, - #[cfg_attr(feature = "serde", serde(with = "As::>>"))] + #[cfg_attr( + feature = "serde", + serde(with = "As::>>") + )] pub fix_duration: Option, pub waypoint_id: Option>, } diff --git a/src/sentences/ztg.rs b/src/sentences/ztg.rs index b76e1a4..3d16ec1 100644 --- a/src/sentences/ztg.rs +++ b/src/sentences/ztg.rs @@ -31,7 +31,10 @@ use super::utils::array_string; #[derive(Debug, PartialEq)] pub struct ZtgData { pub fix_time: Option, - #[cfg_attr(feature = "serde", serde(with = "As::>>"))] + #[cfg_attr( + feature = "serde", + serde(with = "As::>>") + )] pub fix_duration: Option, pub waypoint_id: Option>, } From 3ba54805e26543d5a5efabf6ea5aa4cf7a27fca5 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Fri, 7 Jul 2023 17:41:11 +0200 Subject: [PATCH 06/14] feat: use fmt and marker core --- Cargo.toml | 2 +- src/parser.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d74fbb7..f4c33b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ quickcheck = { version = "1.0.3", default-features = false } criterion = "0.4" [features] -default = ["std", "all-sentences"] +default = ["std", "all-sentences", "serde"] std = ["nom/std", "chrono/std", "arrayvec/std"] serde = [ "serde/derive", diff --git a/src/parser.rs b/src/parser.rs index d3a8edf..0ffa224 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,6 @@ //! The [`Nmea`] parser. -use core::{fmt, mem, ops::BitOr}; +use core::{fmt, marker::PhantomData, mem, ops::BitOr}; use chrono::{NaiveDate, NaiveTime}; use heapless::{Deque, Vec}; @@ -13,8 +13,6 @@ use crate::{ #[cfg(feature = "serde")] use serde::{de::Visitor, ser::SerializeSeq, Deserialize, Serialize}; -#[cfg(feature = "serde")] -use std::marker::PhantomData; /// NMEA parser /// @@ -485,7 +483,7 @@ impl DequeVisitor { impl<'de> Visitor<'de> for DequeVisitor { type Value = Deque, 4>, 15>; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("deque") } From 6a76707b2520b7e7c8dbd14e438e2fce995fc402 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Fri, 7 Jul 2023 17:46:28 +0200 Subject: [PATCH 07/14] chore: remove serde from default features --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f4c33b9..d74fbb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ quickcheck = { version = "1.0.3", default-features = false } criterion = "0.4" [features] -default = ["std", "all-sentences", "serde"] +default = ["std", "all-sentences"] std = ["nom/std", "chrono/std", "arrayvec/std"] serde = [ "serde/derive", From 254dee283e50fc340c4c0eb735f0427650835b02 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Fri, 7 Jul 2023 17:49:26 +0200 Subject: [PATCH 08/14] refactor: make clippy happy --- src/parser.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index 0ffa224..a5bb04f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,6 @@ //! The [`Nmea`] parser. -use core::{fmt, marker::PhantomData, mem, ops::BitOr}; +use core::{fmt, mem, ops::BitOr}; use chrono::{NaiveDate, NaiveTime}; use heapless::{Deque, Vec}; @@ -14,6 +14,9 @@ use crate::{ #[cfg(feature = "serde")] use serde::{de::Visitor, ser::SerializeSeq, Deserialize, Serialize}; +#[cfg(feature = "serde")] +use core::marker::PhantomData; + /// NMEA parser /// /// This struct parses NMEA sentences, including checksum checks and sentence From e308156369f02135079fdece46bb3b686b5f0ceb Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Fri, 7 Jul 2023 18:01:44 +0200 Subject: [PATCH 09/14] feat: do not use PhantomData --- src/parser.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index a5bb04f..3002221 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -14,9 +14,6 @@ use crate::{ #[cfg(feature = "serde")] use serde::{de::Visitor, ser::SerializeSeq, Deserialize, Serialize}; -#[cfg(feature = "serde")] -use core::marker::PhantomData; - /// NMEA parser /// /// This struct parses NMEA sentences, including checksum checks and sentence @@ -469,18 +466,7 @@ where } #[cfg(feature = "serde")] -struct DequeVisitor { - marker: PhantomData Deque, 4>, 15>>, -} - -#[cfg(feature = "serde")] -impl DequeVisitor { - fn new() -> Self { - Self { - marker: PhantomData, - } - } -} +struct DequeVisitor; #[cfg(feature = "serde")] impl<'de> Visitor<'de> for DequeVisitor { @@ -509,7 +495,7 @@ fn deserialize_deque<'de, D>(d: D) -> Result, 4>, 15 where D: serde::Deserializer<'de>, { - d.deserialize_seq(DequeVisitor::new()) + d.deserialize_seq(DequeVisitor) } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] From 0f63995019d5153a1bc0cb4112582708a5b77622 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Fri, 7 Jul 2023 18:53:35 +0200 Subject: [PATCH 10/14] style: fix formatting --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d74fbb7..6d77236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,9 +26,9 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -arrayvec = { version = "0.7.2", default-features = false} +arrayvec = { version = "0.7.2", default-features = false } chrono = { version = "0.4.19", default-features = false } -heapless = { version ="0.7.15"} +heapless = "0.7.15" nom = { version = "7.1.1", default-features = false } # we include num-traits only when `std` is not enabled From 7ce11dd2da28b82d9431a087cc2c7b4fae23bcb4 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Fri, 7 Jul 2023 18:58:06 +0200 Subject: [PATCH 11/14] feat: move deque serializing/deserializing to mod, propagate push_back error, use more specified 'expecting' message --- src/parser.rs | 71 ++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 3002221..093c7cf 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -447,55 +447,56 @@ struct SatsPack { /// BeiDou: 12 + 3 IGSO + 3 GEO /// Galileo: 12 /// => 58 total Satellites => max 15 rows of data - #[cfg_attr(feature = "serde", serde(serialize_with = "serialize_deque"))] - #[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_deque"))] + #[cfg_attr(feature = "serde", serde(with = "serde_deq"))] data: Deque, 4>, 15>, max_len: usize, } #[cfg(feature = "serde")] -fn serialize_deque(v: &Deque, 4>, 15>, s: S) -> Result -where - S: serde::Serializer, -{ - let mut seq = s.serialize_seq(Some(15))?; - for e in v.iter() { - seq.serialize_element(e)?; +mod serde_deq { + use super::*; + + pub fn serialize(v: &Deque, 4>, 15>, s: S) -> Result + where + S: serde::Serializer, + { + let mut seq = s.serialize_seq(Some(15))?; + for e in v.iter() { + seq.serialize_element(e)?; + } + seq.end() } - seq.end() -} -#[cfg(feature = "serde")] -struct DequeVisitor; + struct DequeVisitor; -#[cfg(feature = "serde")] -impl<'de> Visitor<'de> for DequeVisitor { - type Value = Deque, 4>, 15>; + impl<'de> Visitor<'de> for DequeVisitor { + type Value = Deque, 4>, 15>; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("deque") - } + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("deque of vectors containing optional Satellite structs") + } - fn visit_seq(self, mut seq: A) -> Result - where - A: serde::de::SeqAccess<'de>, - { - let mut deq: Deque, 4>, 15> = Deque::new(); + fn visit_seq(self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + let mut deq: Deque, 4>, 15> = Deque::new(); - while let Some(v) = seq.next_element()? { - deq.push_back(v).expect("Cannot deserialize"); - } + while let Some(v) = seq.next_element()? { + deq.push_back(v) + .map_err(|_| serde::de::Error::invalid_length(deq.capacity() + 1, &self))?; + } - Ok(deq) + Ok(deq) + } } -} -#[cfg(feature = "serde")] -fn deserialize_deque<'de, D>(d: D) -> Result, 4>, 15>, D::Error> -where - D: serde::Deserializer<'de>, -{ - d.deserialize_seq(DequeVisitor) + pub fn deserialize<'de, D>(d: D) -> Result, 4>, 15>, D::Error> + where + D: serde::Deserializer<'de>, + { + d.deserialize_seq(DequeVisitor) + } } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] From 29dacae9cb10147f1ff36ecf0101a7fe6cb8f7cf Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Wed, 12 Jul 2023 09:48:44 +0200 Subject: [PATCH 12/14] feat: use DurationSecondsWithFrac instead of DurationSeconds --- src/sentences/zfo.rs | 2 +- src/sentences/ztg.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentences/zfo.rs b/src/sentences/zfo.rs index 9985142..551c6ca 100644 --- a/src/sentences/zfo.rs +++ b/src/sentences/zfo.rs @@ -31,7 +31,7 @@ pub struct ZfoData { pub fix_time: Option, #[cfg_attr( feature = "serde", - serde(with = "As::>>") + serde(with = "As::>>") )] pub fix_duration: Option, pub waypoint_id: Option>, diff --git a/src/sentences/ztg.rs b/src/sentences/ztg.rs index 3d16ec1..b051b94 100644 --- a/src/sentences/ztg.rs +++ b/src/sentences/ztg.rs @@ -33,7 +33,7 @@ pub struct ZtgData { pub fix_time: Option, #[cfg_attr( feature = "serde", - serde(with = "As::>>") + serde(with = "As::>>") )] pub fix_duration: Option, pub waypoint_id: Option>, From 411fc5277a0cc86bc07beb9ad035f55beae1f702 Mon Sep 17 00:00:00 2001 From: Piotr Makowiecki Date: Wed, 12 Jul 2023 09:51:21 +0200 Subject: [PATCH 13/14] doc: add serde to features list --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 63f553f..365a249 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,7 @@ //! //! - `default` features - `std` //! - `std` - enable `std` +//! - `serde` - enable `serde` //! //! [`Nmea::parse()`]: Nmea::parse //! [`Nmea::parse_for_fix()`]: Nmea::parse_for_fix From e5f9bc9df0650c7814d19852a3a18e71fe7179a4 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev <8925621+elpiel@users.noreply.github.com> Date: Thu, 20 Jul 2023 16:02:15 +0300 Subject: [PATCH 14/14] chore: bump MSRV and include std features Signed-off-by: Lachezar Lechev --- .github/workflows/ci.yml | 2 +- Cargo.toml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31ca546..98d0914 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - rust: ["1.60", stable, beta] + rust: ["1.61", stable, beta] env: RUSTUP_MAX_RETRIES: 10 CARGO_NET_RETRY: 10 diff --git a/Cargo.toml b/Cargo.toml index 6d77236..a69dcb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ repository = "https://github.com/AeroRust/nmea" readme = "README.md" edition = "2021" -rust-version = "1.60" +rust-version = "1.61" [package.metadata.docs.rs] all-features = true @@ -29,25 +29,26 @@ rustdoc-args = ["--cfg", "docsrs"] arrayvec = { version = "0.7.2", default-features = false } chrono = { version = "0.4.19", default-features = false } heapless = "0.7.15" -nom = { version = "7.1.1", default-features = false } +nom = { version = "7.1", default-features = false } # we include num-traits only when `std` is not enabled # because of `fract()` and `trunc()` methods num-traits = { version = "0.2", default-features = false, features = ["libm"]} cfg-if = "1" -serde = { version = "1.0.163", default-features = false, optional = true } -serde_with = { version = "3.0.0", default-features = false, optional = true } +serde = { version = "1.0", default-features = false, optional = true } +serde_with = { version = "3.0", default-features = false, optional = true } [dev-dependencies] -approx = "0.5.1" +approx = "0.5" doc-comment = "0.3" pretty_assertions = "1" -quickcheck = { version = "1.0.3", default-features = false } +quickcheck = { version = "1", default-features = false } +# criterion 0.5 has clap_builder version which requires at least Rust 1.64 criterion = "0.4" [features] default = ["std", "all-sentences"] -std = ["nom/std", "chrono/std", "arrayvec/std"] +std = ["nom/std", "chrono/std", "arrayvec/std", "serde?/std", "serde_with?/std"] serde = [ "serde/derive", "serde_with/macros", @@ -57,7 +58,6 @@ serde = [ "arrayvec/serde" ] - all-sentences = ["GNSS", "waypoint", "maritime", "water", "vendor-specific", "other"] # GNSS specific sentences related to the possition or speed relative to the ground GNSS = ["ALM", "GBS", "GGA", "GLL", "GNS", "GSA", "GSV", "RMC", "VTG"]