1- //! AIS parsing library, for reading AIS NMEA sentences
1+ //! AIS parsing library for reading AIS NMEA sentences, with support for JSON serialization.
22//!
3- //! Given an NMEA stream, this library can extract various AIS message types in more detail.
3+ //! This library parses NMEA AIS (Automatic Identification System) sentences and provides
4+ //! structured representations of the data, allowing further processing or analysis.
45//!
5- //! # Example:
6+ //! # Features
7+ //! - Parses AIS NMEA sentences into structured types.
8+ //! - Supports JSON serialization and deserialization for `AisSentence` objects.
9+ //!
10+ //! # Example
611//! ```
7- //! use ais::{AisFragments, AisParser};
12+ //! use ais::{AisFragments, AisParser, serialize_to_json, deserialize_from_json };
813//! use ais::messages::AisMessage;
914//!
10- //! // The line below is an NMEA sentence, much as you'd see coming out of an AIS decoder.
1115//! let line = b"!AIVDM,1,1,,B,E>kb9O9aS@7PUh10dh19@;0Tah2cWrfP:l?M`00003vP100,0*01";
12- //!
1316//! let mut parser = AisParser::new();
14- //! if let AisFragments::Complete(sentence) = parser.parse(line, true)? {
15- //! // This sentence is complete, ie unfragmented
17+ //!
18+ //! if let AisFragments::Complete( sentence) = parser.parse(line, true).unwrap() {
1619//! assert_eq!(sentence.num_fragments, 1);
17- //! // The data was transmitted on AIS channel B
1820//! assert_eq!(sentence.channel, Some('B'));
1921//!
20- //! if let Some(message) = sentence.message {
22+ //! if let Some(ref message) = sentence.message {
2123//! match message {
2224//! AisMessage::AidToNavigationReport(report) => {
2325//! assert_eq!(report.mmsi, 993692028);
2426//! assert_eq!(report.name, "SF OAK BAY BR VAIS E");
25- //! // There are a ton more fields available here
2627//! },
2728//! _ => panic!("Unexpected message type"),
2829//! }
2930//! }
31+ //!
32+ //! let json = serialize_to_json(&sentence).unwrap();
33+ //! let deserialized_sentence = deserialize_from_json(&json).unwrap();
34+ //! assert_eq!(sentence, deserialized_sentence);
3035//! }
31- //! # Ok::<(), ais::errors::Error>(())
3236//! ```
37+
3338#![ cfg_attr( not( feature = "std" ) , no_std) ]
3439
3540#[ doc( hidden) ]
36- /// standard library stuff available crate-wide, regardless of `no_std` state
41+ /// Standard library items, available crate-wide regardless of `no_std` state.
3742pub mod lib {
3843 #[ cfg( all( not( feature = "std" ) , not( feature = "alloc" ) ) ) ]
3944 pub mod std {
@@ -80,6 +85,19 @@ pub mod sentence;
8085pub use errors:: Result ;
8186pub use sentence:: { AisFragments , AisParser } ;
8287
88+ use sentence:: AisSentence ;
89+ use serde_json:: Error as SerdeError ;
90+
91+ /// Serializes an `AisSentence` to JSON
92+ pub fn serialize_to_json ( sentence : & AisSentence ) -> std:: result:: Result < String , SerdeError > {
93+ serde_json:: to_string ( sentence)
94+ }
95+
96+ /// Deserializes an `AisSentence` from JSON
97+ pub fn deserialize_from_json ( json_data : & str ) -> std:: result:: Result < AisSentence , SerdeError > {
98+ serde_json:: from_str ( json_data)
99+ }
100+
83101#[ cfg( test) ]
84102mod test_helpers {
85103 #[ inline]
@@ -94,6 +112,7 @@ mod test_helpers {
94112#[ cfg( test) ]
95113mod tests {
96114 use super :: * ;
115+ use crate :: sentence:: { AisReportType , AisSentence , TalkerId } ;
97116
98117 const TEST_MESSAGES : [ & [ u8 ] ; 8 ] = [
99118 b"!AIVDM,1,1,,B,E>kb9O9aS@7PUh10dh19@;0Tah2cWrfP:l?M`00003vP100,0*01" ,
@@ -108,9 +127,54 @@ mod tests {
108127
109128 #[ test]
110129 fn end_to_end ( ) {
111- let mut parser = sentence :: AisParser :: new ( ) ;
130+ let mut parser = AisParser :: new ( ) ;
112131 for line in TEST_MESSAGES . iter ( ) {
113132 parser. parse ( line, true ) . unwrap ( ) ;
114133 }
115134 }
135+
136+ #[ test]
137+ fn test_json_serialization ( ) {
138+ let mut parser = AisParser :: new ( ) ;
139+ let line = b"!AIVDM,1,1,,B,E>kb9O9aS@7PUh10dh19@;0Tah2cWrfP:l?M`00003vP100,0*01" ;
140+
141+ if let AisFragments :: Complete ( sentence) = parser. parse ( line, true ) . unwrap ( ) {
142+ // Serialize the sentence to JSON
143+ let json = serialize_to_json ( & sentence) . expect ( "Failed to serialize to JSON" ) ;
144+ println ! ( "Serialized JSON: {}" , json) ;
145+
146+ // Deserialize back from JSON
147+ let deserialized_sentence =
148+ deserialize_from_json ( & json) . expect ( "Failed to deserialize from JSON" ) ;
149+
150+ assert_eq ! ( sentence, deserialized_sentence) ;
151+ }
152+ }
153+
154+ #[ test]
155+ fn test_serialize_deserialize ( ) {
156+ // Create a sample AisSentence struct
157+ let original_sentence = AisSentence {
158+ message : None ,
159+ talker_id : TalkerId :: AI ,
160+ report_type : AisReportType :: VDM ,
161+ num_fragments : 1 ,
162+ fragment_number : 1 ,
163+ message_id : Some ( 123 ) ,
164+ channel : Some ( 'A' ) ,
165+ data : vec ! [ 69 , 62 , 107 , 98 , 57 , 79 ] , // sample data; replace with real data if needed
166+ fill_bit_count : 0 ,
167+ message_type : 1 ,
168+ } ;
169+
170+ // Serialize to JSON
171+ let json_data = serialize_to_json ( & original_sentence) . expect ( "Serialization failed" ) ;
172+
173+ // Deserialize back to an AisSentence
174+ let deserialized_sentence: AisSentence =
175+ deserialize_from_json ( & json_data) . expect ( "Deserialization failed" ) ;
176+
177+ // Check if the deserialized struct matches the original
178+ assert_eq ! ( original_sentence, deserialized_sentence) ;
179+ }
116180}
0 commit comments