Skip to content

Commit

Permalink
cargo clippy and cargo fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
ericqu committed Jan 3, 2025
1 parent 352a421 commit 5cc696f
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 48 deletions.
24 changes: 17 additions & 7 deletions iban_validation_polars/src/expression.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use iban_validation_rs;
use polars::prelude::*;
use pyo3_polars::derive::polars_expr;
use iban_validation_rs;

fn process_iban_str_str(value: &str, iban_valid: &mut String) {
*iban_valid = String::from("");
Expand All @@ -9,21 +9,31 @@ fn process_iban_str_str(value: &str, iban_valid: &mut String) {
Ok(valid_iban) => {
iban_valid.push_str(valid_iban.get_iban());
iban_valid.push_str(",");
iban_valid.push_str(valid_iban.iban_bank_id.map(|x| x.to_string()).unwrap_or(String::from("")).as_str());
iban_valid.push_str(
valid_iban
.iban_bank_id
.map(|x| x.to_string())
.unwrap_or(String::from(""))
.as_str(),
);
iban_valid.push_str(",");
iban_valid.push_str(valid_iban.iban_branch_id.map(|x| x.to_string()).unwrap_or(String::from("")).as_str());
iban_valid.push_str(
valid_iban
.iban_branch_id
.map(|x| x.to_string())
.unwrap_or(String::from(""))
.as_str(),
);
}
Err(_) => {
*iban_valid = String::from("");
}
*iban_valid = String::from("");
}
}
}

#[polars_expr(output_type=String)]
fn process_ibans(inputs: &[Series]) -> PolarsResult<Series> {
let ca = inputs[0].str()?;
let out: StringChunked = ca.apply_into_string_amortized(process_iban_str_str);
Ok(out.into_series())
}


2 changes: 1 addition & 1 deletion iban_validation_py/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use pyo3::prelude::*;
fn validate_iban(iban_t: &str) -> PyResult<bool> {
match iban_validation_rs::validate_iban_str(iban_t) {
Ok(_) => Ok(true),
Err(_) => Ok(false)
Err(_) => Ok(false),
}
}

Expand Down
16 changes: 8 additions & 8 deletions iban_validation_rs/benches/speed_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
use iban_validation_rs::validate_iban_str;

pub fn valid_001(c: &mut Criterion) {
c.bench_function("valid 001", |b| b.iter(||
validate_iban_str(black_box("DE44500105175407324931"))));
c.bench_function("valid 001", |b| {
b.iter(|| validate_iban_str(black_box("DE44500105175407324931")))
});
}

pub fn valid_002(c: &mut Criterion) {
Expand Down Expand Up @@ -111,15 +112,14 @@ pub fn valid_002(c: &mut Criterion) {
"DE89370400440532013000",
];

c.bench_function("valid 002", |b| b.iter(||
{
c.bench_function("valid 002", |b| {
b.iter(|| {
for iban in &tc {
let _ = validate_iban_str(black_box(iban));
}
}
));

})
});
}

criterion_group!(benches, valid_001, valid_002);
criterion_main!(benches);
criterion_main!(benches);
66 changes: 34 additions & 32 deletions iban_validation_rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ use std::error::Error;
use std::fmt;
use std::sync::LazyLock;


/// indicate which information is expected from the Iban Registry and in the record.
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IbanFields {
/// two-letter country codes as per ISO 3166-1
pub ctry_cd: [u8;2],
/// two-letter country codes as per ISO 3166-1
pub ctry_cd: [u8; 2],
/// IBAN length, intentionnaly short, the length is sufficient but if something changes it will raise error quickly
pub iban_len: u8,
/// position of bank identifier starting point
Expand Down Expand Up @@ -55,22 +54,18 @@ impl fmt::Display for ValidationError {
impl Error for ValidationError {}

/// utility function to load the registry (as json) into a Hashmap
fn convert_to_hashmap(
json_str: &str,
) -> Result<HashMap<[u8;2], IbanFields>, serde_json::Error> {

fn convert_to_hashmap(json_str: &str) -> Result<HashMap<[u8; 2], IbanFields>, serde_json::Error> {
let items: Vec<IbanFields> = serde_json::from_str(json_str)?;

let map: HashMap<[u8;2], IbanFields> = items.into_iter()
.map(|item| (item.ctry_cd.clone(), item))
.collect();
let map: HashMap<[u8; 2], IbanFields> =
items.into_iter().map(|item| (item.ctry_cd, item)).collect();

Ok(map)
}

/// trigger the loading of the registry once need, and only once.
/// panics if failing as there is no other way forward.
static IB_REG: LazyLock<HashMap<[u8;2], IbanFields>> = LazyLock::new(|| {
static IB_REG: LazyLock<HashMap<[u8; 2], IbanFields>> = LazyLock::new(|| {
convert_to_hashmap(include_str!("../data/iban_definitions.json"))
.expect("Failed parsing JSON data into a HashMap")
});
Expand Down Expand Up @@ -120,11 +115,11 @@ fn simple_contains_c(c: char) -> Result<u8, ValidationLetterError> {
}
}

/// internal utility
/// internal utility
/// division method for modulo 97 >> faster than regular modulo
#[inline]
fn division_mod97(x: u32) -> u32 {
let q = x / 97; // Quotient
let q = x / 97; // Quotient
x - q * 97 // Remainder
}

Expand All @@ -136,8 +131,11 @@ pub const fn get_source_file() -> &'static str {
/// Validate than an Iban is valid according to the registry information
/// return true when Iban is fine, otherwise returns Error.
pub fn validate_iban_str(input_iban: &str) -> Result<bool, ValidationError> {
let identified_country:[u8; 2] = match input_iban.get(..2) {
Some(value) => value.as_bytes().try_into().map_err(|_| ValidationError::InvalidCountry)?,
let identified_country: [u8; 2] = match input_iban.get(..2) {
Some(value) => value
.as_bytes()
.try_into()
.map_err(|_| ValidationError::InvalidCountry)?,
None => return Err(ValidationError::MissingCountry),
};
let pattern: &String = match &IB_REG.get(&identified_country) {
Expand All @@ -150,9 +148,12 @@ pub fn validate_iban_str(input_iban: &str) -> Result<bool, ValidationError> {
}

// There is a potental panic but it should be a dead code, as we should never find a non 2-letter country code given we search for 2-leter country code and found something before
let pattern_start:[u8; 2]= pattern
.get(..2).unwrap()
.as_bytes().try_into().map_err(|_| ValidationError::InvalidCountry)
let pattern_start: [u8; 2] = pattern
.get(..2)
.unwrap()
.as_bytes()
.try_into()
.map_err(|_| ValidationError::InvalidCountry)
.expect("Error the built-in pattern is not starting with at least two characters");

// first two letters do not match
Expand Down Expand Up @@ -185,7 +186,8 @@ pub fn validate_iban_str(input_iban: &str) -> Result<bool, ValidationError> {
true => 0,
_ => return Err(ValidationError::StructureIncorrectForCountry),
},
_ => { // the 2-letter country code should match
_ => {
// the 2-letter country code should match
if p == t {
match simple_contains_a(t) {
Ok(value) => value,
Expand All @@ -196,12 +198,11 @@ pub fn validate_iban_str(input_iban: &str) -> Result<bool, ValidationError> {
}
}
};
acc *= if m97digit < 10 { 10 } else { 100 }; // Multiply by 10 (or 100 for two-digit numbers)
acc = division_mod97(acc + (m97digit as u32)); // and add new digit

acc *= if m97digit < 10 { 10 } else { 100 }; // Multiply by 10 (or 100 for two-digit numbers)
acc = division_mod97(acc + (m97digit as u32)); // and add new digit
}
if acc == 1 {
Ok(true)
Ok(true)
} else {
Err(ValidationError::ModuloIncorrect)
}
Expand All @@ -228,8 +229,11 @@ impl<'a> Iban<'a> {
Err(e) => return Err(e),
};

let identified_country:[u8; 2] = match s.get(..2) {
Some(value) => value.as_bytes().try_into().map_err(|_| ValidationError::InvalidCountry)?,
let identified_country: [u8; 2] = match s.get(..2) {
Some(value) => value
.as_bytes()
.try_into()
.map_err(|_| ValidationError::InvalidCountry)?,
None => return Err(ValidationError::MissingCountry),
};

Expand All @@ -240,8 +244,8 @@ impl<'a> Iban<'a> {

let bank_id = if let Some(start) = iban_data.bank_id_pos_s {
if let Some(end) = iban_data.bank_id_pos_e {
if start <= end && (4+start+(end-start)) <= s.len() {
Some(&s[start+3..4+start+(end-start)])
if start <= end && (4 + start + (end - start)) <= s.len() {
Some(&s[start + 3..4 + start + (end - start)])
} else {
None // Indices are invalid
}
Expand All @@ -254,8 +258,8 @@ impl<'a> Iban<'a> {

let branch_id = if let Some(start) = iban_data.branch_id_pos_s {
if let Some(end) = iban_data.branch_id_pos_e {
if start <= end && (4+start+(end-start)) <= s.len() {
Some(&s[start+3..4+start+(end-start)])
if start <= end && (4 + start + (end - start)) <= s.len() {
Some(&s[start + 3..4 + start + (end - start)])
} else {
None // Indices are invalid
}
Expand Down Expand Up @@ -465,7 +469,6 @@ mod tests {
assert_eq!(the_test.get_iban(), "GE29NB0000000101904917");
assert_eq!(the_test.iban_bank_id.unwrap(), "NB");
assert_eq!(the_test.iban_branch_id, None);

}

#[test]
Expand All @@ -485,7 +488,6 @@ mod tests {

#[test]
fn test_filename() {
assert_eq!( get_source_file(), "iban_registry_v98.txt");
assert_eq!(get_source_file(), "iban_registry_v98.txt");
}

}

0 comments on commit 5cc696f

Please sign in to comment.