From 99b0ec993fa485e227af0c0805c37317fd267cfb Mon Sep 17 00:00:00 2001 From: Michael Macias Date: Fri, 6 Sep 2024 11:10:19 -0500 Subject: [PATCH] vcf/variant/record/info/field/value/array/values: Fix iterating over an empty lists This now immediately returns `None`. --- noodles-vcf/CHANGELOG.md | 5 + .../record/info/field/value/array/values.rs | 91 +++++++++++-------- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/noodles-vcf/CHANGELOG.md b/noodles-vcf/CHANGELOG.md index 94e02af50..9923747a3 100644 --- a/noodles-vcf/CHANGELOG.md +++ b/noodles-vcf/CHANGELOG.md @@ -16,6 +16,11 @@ * vcf/variant/record/info/field/value/array/values: Fix counting number of values. + * vcf/variant/record/info/field/value/array/values: Fix iterating over empty + lists. + + This now immediately returns `None`. + ## 0.63.0 - 2024-09-04 ### Added diff --git a/noodles-vcf/src/variant/record/info/field/value/array/values.rs b/noodles-vcf/src/variant/record/info/field/value/array/values.rs index 36510fac8..6d15fa62d 100644 --- a/noodles-vcf/src/variant/record/info/field/value/array/values.rs +++ b/noodles-vcf/src/variant/record/info/field/value/array/values.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, io}; +use std::{borrow::Cow, io, iter}; use crate::io::reader::record_buf::value::percent_decode; @@ -21,15 +21,19 @@ impl<'a> Values<'a, i32> for &'a str { } fn iter(&self) -> Box>> + '_> { - Box::new(self.split(DELIMITER).map(|s| { - match s { - MISSING => Ok(None), - _ => s - .parse() - .map(Some) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), - } - })) + if self.is_empty() { + Box::new(iter::empty()) + } else { + Box::new(self.split(DELIMITER).map(|s| { + match s { + MISSING => Ok(None), + _ => s + .parse() + .map(Some) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), + } + })) + } } } @@ -39,15 +43,19 @@ impl<'a> Values<'a, f32> for &'a str { } fn iter(&self) -> Box>> + '_> { - Box::new(self.split(DELIMITER).map(|s| { - match s { - MISSING => Ok(None), - _ => s - .parse() - .map(Some) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), - } - })) + if self.is_empty() { + Box::new(iter::empty()) + } else { + Box::new(self.split(DELIMITER).map(|s| { + match s { + MISSING => Ok(None), + _ => s + .parse() + .map(Some) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), + } + })) + } } } @@ -59,15 +67,19 @@ impl<'a> Values<'a, char> for &'a str { fn iter(&self) -> Box>> + '_> { const MISSING: char = '.'; - Box::new( - self.split(DELIMITER) - .flat_map(|t| t.chars()) - .map(|c| match c { - MISSING => None, - _ => Some(c), - }) - .map(Ok), - ) + if self.is_empty() { + Box::new(iter::empty()) + } else { + Box::new( + self.split(DELIMITER) + .flat_map(|t| t.chars()) + .map(|c| match c { + MISSING => None, + _ => Some(c), + }) + .map(Ok), + ) + } } } @@ -77,14 +89,18 @@ impl<'a> Values<'a, Cow<'a, str>> for &'a str { } fn iter(&self) -> Box>>> + '_> { - Box::new(self.split(DELIMITER).map(|s| { - match s { - MISSING => Ok(None), - _ => percent_decode(s) - .map(Some) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), - } - })) + if self.is_empty() { + Box::new(iter::empty()) + } else { + Box::new(self.split(DELIMITER).map(|s| { + match s { + MISSING => Ok(None), + _ => percent_decode(s) + .map(Some) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), + } + })) + } } } @@ -109,6 +125,9 @@ mod tests { let values: Box>> = Box::new(src); assert_eq!(values.len(), 0); + let mut iter = values.iter(); + assert!(iter.next().transpose()?.is_none()); + let src = "a,b%3Bc"; let values: Box>> = Box::new(src); assert_eq!(values.len(), 2);