///|
pub(all) struct StringCountEntry {
key_value : String
mut count_value : Int
} derive(Eq, Debug)
///|
pub(all) struct ChecksumCountEntry {
status_value : ChecksumStatus
mut count_value : Int
} derive(Eq, Debug)
///|
pub(all) struct BatchSummary {
total_value : Int
successes_value : Int
failures_value : Int
formatter_entries_value : Array[StringCountEntry]
talker_entries_value : Array[StringCountEntry]
checksum_entries_value : Array[ChecksumCountEntry]
error_entries_value : Array[StringCountEntry]
} derive(Eq, Debug)
///|
pub(all) struct NmeaBatch {
items_value : Array[SentenceResult[NmeaRecord]]
summary_value : BatchSummary
} derive(Eq, Debug)
///|
fn increment_string(entries : Array[StringCountEntry], key : String) -> Unit {
for entry in entries {
if entry.key_value == key {
entry.count_value += 1
return
}
}
entries.push({ key_value: key, count_value: 1 })
}
///|
fn increment_checksum(
entries : Array[ChecksumCountEntry],
status : ChecksumStatus,
) -> Unit {
for entry in entries {
if entry.status_value == status {
entry.count_value += 1
return
}
}
entries.push({ status_value: status, count_value: 1 })
}
///|
fn checksum_status_for_error(error : NmeaError) -> ChecksumStatus {
if error.code() == "checksum.mismatch" {
PresentInvalid
} else if error.code() == "checksum.missing" {
MissingChecksum
} else {
NotChecked
}
}
///|
fn batch_from_frames(frames : Array[NmeaFrame]) -> NmeaBatch {
let items : Array[SentenceResult[NmeaRecord]] = []
let formatter_entries : Array[StringCountEntry] = []
let talker_entries : Array[StringCountEntry] = []
let checksum_entries : Array[ChecksumCountEntry] = []
let error_entries : Array[StringCountEntry] = []
let mut successes = 0
let mut failures = 0
for index = 0; index < frames.length(); index = index + 1 {
let frame = frames[index]
let status = frame.checksum_status()
increment_checksum(checksum_entries, status)
match parse_record(frame) {
Ok(record) => {
successes += 1
increment_string(formatter_entries, record.formatter())
increment_string(talker_entries, record.talker())
items.push(
SentenceResult::ok(
index,
record.formatter(),
status,
value=Some(record),
),
)
}
Err(error) => {
failures += 1
increment_string(error_entries, error.code())
items.push(SentenceResult::err(index, status, error))
}
}
}
{
items_value: items,
summary_value: {
total_value: frames.length(),
successes_value: successes,
failures_value: failures,
formatter_entries_value: formatter_entries,
talker_entries_value: talker_entries,
checksum_entries_value: checksum_entries,
error_entries_value: error_entries,
},
}
}
///|
pub fn analyze_frame_batch(frames : Array[NmeaFrame]) -> NmeaBatch {
batch_from_frames(frames)
}
///|
pub fn parse_batch(
inputs : Array[String],
policy? : ParsePolicy = Strict,
limits? : FrameLimits = FrameLimits::standard(),
) -> NmeaBatch {
let items : Array[SentenceResult[NmeaRecord]] = []
let formatter_entries : Array[StringCountEntry] = []
let talker_entries : Array[StringCountEntry] = []
let checksum_entries : Array[ChecksumCountEntry] = []
let error_entries : Array[StringCountEntry] = []
let mut successes = 0
let mut failures = 0
for index = 0; index < inputs.length(); index = index + 1 {
match parse_frame(inputs[index], policy~, limits~) {
Err(error) => {
failures += 1
let status = checksum_status_for_error(error)
increment_checksum(checksum_entries, status)
increment_string(error_entries, error.code())
items.push(SentenceResult::err(index, status, error))
}
Ok(frame) => {
let status = frame.checksum_status()
increment_checksum(checksum_entries, status)
match parse_record(frame) {
Ok(record) => {
successes += 1
increment_string(formatter_entries, record.formatter())
increment_string(talker_entries, record.talker())
items.push(
SentenceResult::ok(
index,
record.formatter(),
status,
value=Some(record),
),
)
}
Err(error) => {
failures += 1
increment_string(error_entries, error.code())
items.push(SentenceResult::err(index, status, error))
}
}
}
}
}
{
items_value: items,
summary_value: {
total_value: inputs.length(),
successes_value: successes,
failures_value: failures,
formatter_entries_value: formatter_entries,
talker_entries_value: talker_entries,
checksum_entries_value: checksum_entries,
error_entries_value: error_entries,
},
}
}
///|
fn string_count(entries : Array[StringCountEntry], key : String) -> Int {
for entry in entries {
if entry.key_value == key {
return entry.count_value
}
}
0
}
///|
pub fn StringCountEntry::key(self : StringCountEntry) -> String {
self.key_value
}
///|
pub fn StringCountEntry::count(self : StringCountEntry) -> Int {
self.count_value
}
///|
pub fn ChecksumCountEntry::status(self : ChecksumCountEntry) -> ChecksumStatus {
self.status_value
}
///|
pub fn ChecksumCountEntry::count(self : ChecksumCountEntry) -> Int {
self.count_value
}
///|
pub fn BatchSummary::total(self : BatchSummary) -> Int {
self.total_value
}
///|
pub fn BatchSummary::successes(self : BatchSummary) -> Int {
self.successes_value
}
///|
pub fn BatchSummary::failures(self : BatchSummary) -> Int {
self.failures_value
}
///|
pub fn BatchSummary::formatter_entries(
self : BatchSummary,
) -> Array[StringCountEntry] {
self.formatter_entries_value.copy()
}
///|
pub fn BatchSummary::talker_entries(
self : BatchSummary,
) -> Array[StringCountEntry] {
self.talker_entries_value.copy()
}
///|
pub fn BatchSummary::checksum_entries(
self : BatchSummary,
) -> Array[ChecksumCountEntry] {
self.checksum_entries_value.copy()
}
///|
pub fn BatchSummary::error_entries(
self : BatchSummary,
) -> Array[StringCountEntry] {
self.error_entries_value.copy()
}
///|
pub fn BatchSummary::formatter_count(self : BatchSummary, key : String) -> Int {
string_count(self.formatter_entries_value, key)
}
///|
pub fn BatchSummary::talker_count(self : BatchSummary, key : String) -> Int {
string_count(self.talker_entries_value, key)
}
///|
pub fn BatchSummary::error_count(self : BatchSummary, key : String) -> Int {
string_count(self.error_entries_value, key)
}
///|
pub fn BatchSummary::checksum_count(
self : BatchSummary,
status : ChecksumStatus,
) -> Int {
for entry in self.checksum_entries_value {
if entry.status_value == status {
return entry.count_value
}
}
0
}
///|
pub fn NmeaBatch::items(self : NmeaBatch) -> Array[SentenceResult[NmeaRecord]] {
self.items_value.copy()
}
///|
pub fn NmeaBatch::summary(self : NmeaBatch) -> BatchSummary {
self.summary_value
}