### Display and as_brief_str examples Source: https://docs.rs/sameold/latest/sameold/enum.Phenomenon.html?search=u32+-%3E+bool Examples showing how `Phenomenon` implements `Display` and provides `as_brief_str()` for human-readable descriptions. ```rust use std::fmt; assert_eq!(format!("{}", Phenomenon::HazardousMaterials), "Hazardous Materials"); assert_eq!(Phenomenon::HazardousMaterials.as_brief_str(), "Hazardous Materials"); ``` -------------------------------- ### into_ok example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows how to use into_ok on a Result that is guaranteed to be Ok. The example creates a Result from only_good_news() and extracts the Ok value. ```rust let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### Example SAME header in ASCII Source: https://docs.rs/sameold An example SAME header as received in ASCII format. It contains the originator, event code, location codes, and other fields. ```text ZCZC-WXR-RWT-567890-888990+0015-0321115-KLOX/NWS- ``` -------------------------------- ### SAME header example (ASCII) Source: https://docs.rs/sameold/latest/sameold/index.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Example SAME header as received in ASCII format. This is the raw header string that would be decoded by the sameold crate. ```text ZCZC-WXR-RWT-012345-567890-888990+0015-0321115-KLOX/NWS- ``` -------------------------------- ### FIR filter usage examples Source: https://docs.rs/sameold/latest/src/sameold/receiver/filter.rs.html?search=u32+-%3E+bool These examples illustrate the usage of FilterCoeff and Window for FIR filtering. The first and third blocks show the sliding window representation, the second block demonstrates creating a filter and filtering a history slice, and the fourth block shows creating a Window and pushing samples. ```txt // the sample L is the youngest sample, and O is the oldest // [ O | N | M | L ] ``` ```ignore let coeff = FilterCoeff::from_slice(&[1.0f32]); // this is the identity filter let history = &[1.0f32, 2.0f32, 3.0f32, 4.0f32]; // sample history slice let out = coeff.filter(history); // out is 4.0f32 ``` ```txt // the sample K is now the youngest sample // [ N | M | L | K ] ``` ```ignore let wind : Window = Window::new(4); wind.push(&[1.0f32, 2.0f32, 3.0f32, 4.0f32]); ``` -------------------------------- ### or example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the or method, which returns the second Result if the first is Err, otherwise returns the first Ok. The example includes multiple cases with different combinations of Ok and Err. ```rust let x: Result = Ok(2); let y: Result = Err("late error"); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("early error"); let y: Result = Ok(2); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("not a 2"); let y: Result = Err("late error"); assert_eq!(x.or(y), Err("late error")); let x: Result = Ok(2); let y: Result = Ok(100); assert_eq!(x.or(y), Ok(2)); ``` -------------------------------- ### Example: Parsing event code with MessageHeader::event() Source: https://docs.rs/sameold/latest/sameold/struct.MessageHeader.html?search=u32+-%3E+bool Shows how to construct a MessageHeader from a SAME header string and use the event() method to get the phenomenon and significance level. The example asserts the decoded values and the Display output. ```rust use sameplace::{MessageHeader, Phenomenon, SignificanceLevel}; let msg = MessageHeader::new("ZCZC-WXR-RWT-012345+0351-3662322-NOCALL -").unwrap(); let evt = msg.event(); assert_eq!(evt.phenomenon(), Phenomenon::RequiredWeeklyTest); assert_eq!(evt.significance(), SignificanceLevel::Test); assert_eq!(format!("{}", evt), "Required Weekly Test"); ``` -------------------------------- ### as_brief_str example Source: https://docs.rs/sameold/latest/sameold/enum.Phenomenon.html?search=u32+-%3E+bool Shows how to use as_brief_str to get a brief description without severity information. The example asserts that the brief string for RadiologicalHazard is "Radiological Hazard". ```rust assert_eq!(Phenomenon::RadiologicalHazard.as_brief_str(), "Radiological Hazard"); ``` -------------------------------- ### and example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the behavior of the and method on Result. It shows that and returns the second Result if the first is Ok, otherwise returns the first Err. The example includes multiple cases with different combinations of Ok and Err. ```rust let x: Result = Ok(2); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("late error")); let x: Result = Err("early error"); let y: Result<&str, &str> = Ok("foo"); assert_eq!(x.and(y), Err("early error")); let x: Result = Err("not a 2"); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("not a 2")); let x: Result = Ok(2); let y: Result<&str, &str> = Ok("different result type"); assert_eq!(x.and(y), Ok("different result type")); ``` -------------------------------- ### unwrap_or example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the unwrap_or method, which returns the contained Ok value or a provided default. The example shows both Ok and Err cases. ```rust let default = 2; let x: Result = Ok(9); assert_eq!(x.unwrap_or(default), 9); let x: Result = Err("error"); assert_eq!(x.unwrap_or(default), default); ``` -------------------------------- ### Example for Result::ok Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Converts a Result to an Option, returning Some for Ok and None for Err. ```rust let x: Result = Ok(2); assert_eq!(x.ok(), Some(2)); let x: Result = Err("Nothing here"); assert_eq!(x.ok(), None); ``` -------------------------------- ### and_then example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the and_then method, which calls a closure if the Result is Ok, otherwise returns the Err. The example defines a function sq_then_to_string that squares a number and converts to string, and shows how and_then chains fallible operations. ```rust fn sq_then_to_string(x: u32) -> Result { x.checked_mul(x).map(|sq| sq.to_string()).ok_or("overflowed") } assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string())); assert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err("overflowed")); assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number")); ``` ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` -------------------------------- ### unwrap_or_else example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the unwrap_or_else method, which returns the contained Ok value or computes it from a closure. The example defines a function count and shows its usage. ```rust fn count(x: &str) -> usize { x.len() } ``` -------------------------------- ### Example for Result::as_ref Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Converts a Result to a Result of references, leaving the original in place. ```rust let x: Result = Ok(2); assert_eq!(x.as_ref(), Ok(&2)); let x: Result = Err("Error"); assert_eq!(x.as_ref(), Err(&"Error")); ``` -------------------------------- ### unwrap basic usage example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows that unwrap returns the contained Ok value. ```rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### Initialize Equalizer with Coefficients and Windows Source: https://docs.rs/sameold/latest/src/sameold/receiver/equalize.rs.html Constructs the equalizer state with feedforward and feedback coefficients and windows. Asserts that coefficient and window lengths match. Sets mode to EnabledFeedback. ```rust let feedback_wind = Window::new(nfeedback); assert_eq!(feedforward_coeff.inner().len(), feedforward_wind.len()); assert_eq!(feedback_coeff.inner().len(), feedback_wind.len()); Self { relaxation, regularization, train_to, feedforward_coeff, feedback_coeff, feedforward_wind, feedback_wind, mode: EqualizerState::EnabledFeedback, } ``` -------------------------------- ### iter Example: Iterating over the contained value Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows how to use Result::iter to get an iterator that yields one value if Ok, otherwise none. ```rust let x: Result = Ok(7); assert_eq!(x.iter().next(), Some(&7)); let x: Result = Err("nothing!"); assert_eq!(x.iter().next(), None); ``` -------------------------------- ### expect recommended message style example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows the recommended style for expect messages, using 'should' to describe the expectation. ```rust let path = std::env::var("IMPORTANT_PATH") .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`"); ``` -------------------------------- ### unwrap_or_default example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows how unwrap_or_default returns the contained value or the default for the type, using string parsing as an example. ```rust let good_year_from_input = "1909"; let bad_year_from_input = "190blarg"; let good_year = good_year_from_input.parse().unwrap_or_default(); let bad_year = bad_year_from_input.parse().unwrap_or_default(); assert_eq!(1909, good_year); assert_eq!(0, bad_year); ``` -------------------------------- ### sameold crate documentation with SameReceiverBuilder example Source: https://docs.rs/sameold/latest/src/sameold/lib.rs.html?search=std%3A%3Avec Crate-level documentation for sameold, a SAME/EAS demodulator and decoder in Rust. It explains the dual MIT/Apache 2.0 licensing, the safety disclaimer, and the required audio input (mono f32 samples at a sampling rate of at least 8000 Hz). The example shows building a SameReceiver with a builder, configuring AGC, squelch, and preamble error limits, then iterating over decoded messages. It also documents the modem behavior: three bursts are used for error correction, two for error detection, and one for fast EOM; headers incur a 1.311-second delay while trailers do not. ```rust 1//! # sameold: SAME/EAS Demodulation 2//! 3//! *Over-the-air weather alerts for your desktop or RPi.* 4//! 5//! This crate provides a digital demodulator and decoder for 6//! [Specific Area Message Encoding](https://en.wikipedia.org/wiki/Specific_Area_Message_Encoding) 7//! (SAME). It can detect the presence of SAME messages in an audio signal 8//! and report them to the caller. 9//! 10//! ## Disclaimer 11//! 12//! This crate is dual-licensed MIT and Apache 2.0. Read these licenses 13//! carefully as they may affect your rights. 14//! //! This crate has not been certified as a weather radio receiver or for any //! other purpose. The author **strongly discourages** its use in any //! safety-critical applications. Always have at least two methods available //! for receiving weather alerts. //! //! ## Example //! //! A complete example may be found in our //! [`samedec`](https://crates.io/crates/samedec) crate, which provides a //! command-line program for decoding SAME via pipes. //! //! ### Demodulation and Decoding //! //! You will first need to recover *baseband audio* from a radio or //! television station which broadcasts SAME signals. Obtain the //! audio signal that you would normally listen to. You can use //! either //! //! * an audio "line out" jack from a radio, scanner, or other //! receiver; OR //! * a software-defined radio //! //! In either case, obtaining the audio is beyond the scope of this //! crate. To sample your soundcard, try //! [cpal](https://crates.io/crates/cpal). If you have a stereo //! signal, mix to mono first. If you are demodulating wideband FM, //! and your demodulator offers you a choice, choose mono-only //! demodulation. //! //! ``` //! use sameold::{Message, SameReceiverBuilder}; //! //! # let some_audio_source_iterator = || std::iter::once(0.0f32); //! // Create a SameReceiver with your audio sampling rate //! // Sound cards typically run at 44100 Hz or 48000 Hz. Use //! // an input rate of at least 8000 Hz. //! let mut rx = SameReceiverBuilder::new(48000) //! .with_agc_bandwidth(0.05) // AGC bandwidth at symbol rate, < 1.0 //! .with_agc_gain_limits(1.0/(i16::MAX as f32), 1.0/200.0) // for i16 //! .with_squelch_power(0.10, 0.05) // squelch open/close power, 0.0 < power < 1.0 //! .with_preamble_max_errors(2) // bit error limit when detecting sync sequence //! .build(); //! //! // let audiosrc be an iterator which outputs audio samples, //! // such as a BufReader bound to stdin or a file, in f32 //! // format at the sampling rate (here 48000 Hz) //! let audiosrc = some_audio_source_iterator(); //! for msg in rx.iter_messages(audiosrc) { //! match msg { //! Message::StartOfMessage(hdr) => { //! println!("begin SAME voice message: {}", hdr); //! } //! Message::EndOfMessage => { //! println!("end SAME voice message"); //! } //! } //! } //! ``` //! //! The digital receiver is created via a //! [builder](crate::SameReceiverBuilder). //! //! The [`SameReceiver`] binds by iterator to any //! source of `f32` PCM mono (1-channel) audio samples. If you're using `i16` //! samples (as most sound cards do), you'll need to cast them to `f32`. //! There is no need to scale them as long as you configure the //! AGC properly, as above. //! //! The [`iter_messages()`](crate::SameReceiver::iter_messages()) iterator //! consumes as many samples as possible until the next [`Message`] is decoded. //! //! ### Modem Behavior //! //! | # of Bursts | Decoding Strategy | //! |-------------|------------------------------------| //! | 1 | Fast EOM / `NNNN` only | //! | 2 | Error detection (equality checks) | //! | 3 | Error correction (bit voting) | //! //! SAME messages are always transmitted three times, in separate "bursts," for //! redundancy. When decoding the start of message *headers* (`ZCZC`), `sameold` //! will use all three bursts together to improve decoding—if possible. //! //! If one retransmission is missed, `sameold` will automatically fall back to //! decoding with only two bursts. The decoder imposes a delay of approximately //! **1.311 seconds** on all received headers. This delay is not usually //! problematic as most SAME messages are prefixed with a Warning Alarm Tone that //! is not information-bearing. //! //! The message *trailers* are not subject to the same error-correction process //! and delay as the headers. The end-of-message indicator (`NNNN`) will be //! printed just soon as it is received and decoded. //! //! The modem contains duplicate-suppression logic. Identical messages which ``` -------------------------------- ### is_recognized example Source: https://docs.rs/sameold/latest/sameold/enum.Phenomenon.html?search=u32+-%3E+bool Shows how to use is_recognized to check if a phenomenon is recognized. The example asserts that Phenomenon::TropicalStorm returns true. ```rust assert!(Phenomenon::TropicalStorm.is_recognized()); ``` -------------------------------- ### is_unrecognized example Source: https://docs.rs/sameold/latest/sameold/enum.Phenomenon.html?search=u32+-%3E+bool Shows how to use is_unrecognized to check if a phenomenon is not recognized. The example asserts that Phenomenon::Unrecognized returns true. ```rust assert!(Phenomenon::Unrecognized.is_unrecognized()); ``` -------------------------------- ### Category assertion examples Source: https://docs.rs/sameold/latest/sameold/enum.Phenomenon.html?search=u32+-%3E+bool Examples of using category methods like `is_national()`, `is_test()`, `is_weather()`, and `is_non_weather()` on `Phenomenon` variants. ```rust assert!(Phenomenon::NationalPeriodicTest.is_national()); assert!(Phenomenon::NationalPeriodicTest.is_test()); assert!(Phenomenon::SevereThunderstorm.is_weather()); assert!(Phenomenon::Fire.is_non_weather()); ``` -------------------------------- ### Example for Result::is_ok_and Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows is_ok_and with a predicate, including a case with as_ref to avoid moving the value. ```rust let x: Result = Ok(2); assert_eq!(x.is_ok_and(|x| x > 1), true); let x: Result = Ok(0); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Err("hey"); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Ok("ownership".to_string()); assert_eq!(x.as_ref().is_ok_and(|x| x.len() > 1), true); println!("still alive {:?}", x); ``` -------------------------------- ### Example for Result::is_ok Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the is_ok method on Result, returning true for Ok and false for Err. ```rust let x: Result = Ok(-3); assert_eq!(x.is_ok(), true); let x: Result = Err("Some error message"); assert_eq!(x.is_ok(), false); ``` -------------------------------- ### into_err example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Shows how to use into_err on a Result that is guaranteed to be Err. The example defines a function only_bad_news() that returns Result and extracts the Err value. ```rust fn only_bad_news() -> Result { Err("Oops, it failed".into()) } let error: String = only_bad_news().into_err(); println!("{error}"); ``` -------------------------------- ### Window::new Source: https://docs.rs/sameold/latest/src/sameold/receiver/filter.rs.html Creates a new Window with the given length, filled with zeros. ```APIDOC ## Window::new ### Description Creates a new Window with the given length, filled with zeros. ### Method new ### Signature pub fn new(len: usize) -> Self ### Parameters - **len** (usize) - Required - The length of the window. ### Returns - **Self** - A new Window instance. ``` -------------------------------- ### Enter Training Mode Source: https://docs.rs/sameold/latest/src/sameold/receiver/equalize.rs.html Puts the equalizer into training mode, enabled and reset to the start of the training sequence. Returns an error if no training sequence is configured. The next 32 symbols (64 samples) must be the training sequence. ```rust pub fn train(&mut self) -> Result<(), NoTrainingSequenceErr> { let train_to = self.train_to.ok_or(NoTrainingSequenceErr)?; self.mode = EqualizerState::EnabledTraining(train_to, 0); Ok(()) } ``` -------------------------------- ### Example for Result::map Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Maps a Result's Ok value using a function, leaving Err untouched. Example parses lines and multiplies by two. ```rust let line = "1\n2\n3\n4\n"; for num in line.lines() { match num.parse::().map(|i| i * 2) { Ok(n) => println!("{n}"), Err(..) => {} } } ``` -------------------------------- ### or_else example Source: https://docs.rs/sameold/latest/sameold/type.MessageResult.html Demonstrates the or_else method, which calls a closure if the Result is Err, otherwise returns the Ok. The example defines functions sq and err and shows how or_else can be chained. ```rust fn sq(x: u32) -> Result { Ok(x * x) } fn err(x: u32) -> Result { Err(x) } assert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2)); assert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2)); assert_eq!(Err(3).or_else(sq).or_else(err), Ok(9)); assert_eq!(Err(3).or_else(err).or_else(err), Err(3)); ``` -------------------------------- ### byte_samples format for input() Source: https://docs.rs/sameold/latest/src/sameold/receiver/equalize.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Shows the expected format of the byte_samples slice passed to input(). The slice must contain 16 samples representing 8 symbols, with symbol estimates in odd indices. ```txt let byte_samples = [0.0f32, 1.0, 0.0, -1.0, …]; ``` -------------------------------- ### Create and push to Window for FIR filtering Source: https://docs.rs/sameold/latest/src/sameold/receiver/filter.rs.html?search=std%3A%3Avec Creates a sliding window of length 4 and pushes a sample history. Use a Window with the same length as the FilterCoeff for FIR filtering. ```rust let wind : Window = Window::new(4); wind.push(&[1.0f32, 2.0f32, 3.0f32, 4.0f32]); ``` -------------------------------- ### Displaying Originator as human-readable string Source: https://docs.rs/sameold/latest/sameold/enum.Originator.html?search= Shows how to get a human-readable display string for an `Originator` using `as_display_str`, `Display` formatting, and `as_ref`. ```rust assert_eq!("National Weather Service", orig.as_display_str()); assert_eq!("National Weather Service", &format!("{}", orig)); assert_eq!("WXR", orig.as_ref()); assert_eq!("WXR", &format!("{:#}", orig)); ``` -------------------------------- ### Example: Handling unrecognized event codes Source: https://docs.rs/sameold/latest/sameold/struct.MessageHeader.html?search=u32+-%3E+bool Shows that unrecognized event codes are still valid and can be accessed via event_str() and event(). The example demonstrates that the significance level may be Unknown and the event is marked as unrecognized. ```rust let msg = MessageHeader::new("ZCZC-WXR-OMG-012345+0351-3662322-NOCALL -").unwrap(); assert_eq!(msg.event_str(), "OMG"); assert_eq!(msg.event().to_string(), "Unrecognized Warning"); assert_eq!(msg.event().significance(), SignificanceLevel::Unknown); assert!(msg.event().is_unrecognized()); ``` -------------------------------- ### SameReceiverBuilder::new constructor Source: https://docs.rs/sameold/latest/src/sameold/receiver/builder.rs.html?search= Initializes a new builder with default values. The input_rate in Hz is the only mandatory parameter. ```rust pub fn new(input_rate: u32) -> Self { Self { input_rate, dc_blocker_len: 0.38, agc_bandwidth: 0.01f32, agc_gain_limits: [0.0, 1.0e6], timing_bandwidth_unlocked: 0.125f32, timing_bandwidth_locked: 0.05f32, timing_max_deviation: 0.01, squelch_power_open: 0.10, squelch_power_close: 0.05, squelch_bandwidth: 0.125, preamble_max_errors: 2, equalizer: Some(EqualizerBuilder::default()), frame_prefix_max_errors: 2, frame_max_invalid_bytes: 5, } } ``` -------------------------------- ### frame_prefix_max_errors Source: https://docs.rs/sameold/latest/sameold/struct.SameReceiverBuilder.html?search=std%3A%3Avec Returns the maximum frame start bit errors. ```APIDOC ## frame_prefix_max_errors ### Description Returns the maximum frame start bit errors. ### Method `pub fn frame_prefix_max_errors(&self) -> u32` ### Returns - `u32` - Maximum frame start bit errors. ```