Skip to content

Commit

Permalink
disallow repeated num,scaled,seed in same param str
Browse files Browse the repository at this point in the history
  • Loading branch information
bluegenes committed Oct 8, 2024
1 parent 8f08f1b commit bb0e9dd
Showing 1 changed file with 56 additions and 17 deletions.
73 changes: 56 additions & 17 deletions src/utils/buildutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ use sourmash::signature::Signature;
use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fmt::Display;
use std::hash::{Hash, Hasher};
use std::io::{Cursor, Write};
use std::num::ParseIntError;
use std::str::FromStr;
use tokio::fs::File;
use tokio_util::compat::Compat;

Expand Down Expand Up @@ -81,22 +84,31 @@ impl BuildParams {
.map_err(|_| format!("cannot parse k='{}' as a valid integer", value))
}

pub fn parse_num(value: &str) -> Result<u32, String> {
value
.parse::<u32>()
.map_err(|_| format!("cannot parse num='{}' as a valid integer", value))
}
// disallow repeated values for scaled, num, seed
pub fn parse_int_once<T>(
value: &str,
field: &str,
current: &mut Option<T>,
) -> Result<(), String>
where
T: FromStr<Err = ParseIntError> + Display + Copy,
{
let parsed_value = value
.parse::<T>()
.map_err(|_| format!("cannot parse {}='{}' as a valid integer", field, value))?;

// Check for conflicts; we don't allow multiple values for the same field.
if let Some(old_value) = *current {
return Err(format!(
"Conflicting values for '{}': {} and {}",
field, old_value, parsed_value
));
}

pub fn parse_scaled(value: &str) -> Result<u64, String> {
value
.parse::<u64>()
.map_err(|_| format!("cannot parse scaled='{}' as a valid integer", value))
}
// Set the new value.
*current = Some(parsed_value);

pub fn parse_seed(value: &str) -> Result<u32, String> {
value
.parse::<u32>()
.map_err(|_| format!("cannot parse seed='{}' as a valid integer", value))
Ok(())
}

pub fn parse_moltype(
Expand Down Expand Up @@ -164,13 +176,13 @@ impl BuildParams {
Self::parse_moltype(item, &mut moltype)?;
}
_ if item.starts_with("num=") => {
num = Some(Self::parse_num(&item[4..])?);
Self::parse_int_once(&item[4..], "num", &mut num)?;
}
_ if item.starts_with("scaled=") => {
scaled = Some(Self::parse_scaled(&item[7..])?);
Self::parse_int_once(&item[7..], "scaled", &mut scaled)?;
}
_ if item.starts_with("seed=") => {
seed = Some(Self::parse_seed(&item[5..])?);
Self::parse_int_once(&item[5..], "seed", &mut seed)?;
}
_ => return Err(format!("unknown component '{}' in params string", item)),
}
Expand Down Expand Up @@ -1131,6 +1143,33 @@ mod tests {
);
}

#[test]
fn test_repeated_values() {
// repeated scaled
let result = BuildParamsSet::from_params_str("k=31,scaled=1,scaled=1000".to_string());
assert!(result.is_err(), "Expected an error but got Ok.");
assert_eq!(
result.unwrap_err(),
"Conflicting values for 'scaled': 1 and 1000"
);

// repeated num
let result = BuildParamsSet::from_params_str("k=31,num=1,num=1000".to_string());
assert!(result.is_err(), "Expected an error but got Ok.");
assert_eq!(
result.unwrap_err(),
"Conflicting values for 'num': 1 and 1000"
);

// repeated seed
let result = BuildParamsSet::from_params_str("k=31,seed=1,seed=42".to_string());
assert!(result.is_err(), "Expected an error but got Ok.");
assert_eq!(
result.unwrap_err(),
"Conflicting values for 'seed': 1 and 42"
);
}

#[test]
fn test_missing_ksize() {
// Test for a missing ksize, using default should not result in an error.
Expand Down

0 comments on commit bb0e9dd

Please sign in to comment.