From b3f3386f80c14c1490d7a1b47f83dc80456be0ec Mon Sep 17 00:00:00 2001 From: Ivor D'Souza Date: Fri, 22 Nov 2024 19:46:31 +0000 Subject: [PATCH 1/6] feat(crc32): add crc32 hash fn --- Cargo.lock | 5 +-- Cargo.toml | 2 ++ benches/stdlib.rs | 10 ++++++ src/stdlib/crc32.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/stdlib/mod.rs | 3 ++ 5 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/stdlib/crc32.rs diff --git a/Cargo.lock b/Cargo.lock index 2202f7293..084948a42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -743,9 +743,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -3712,6 +3712,7 @@ dependencies = [ "codespan-reporting", "community-id", "convert_case 0.6.0", + "crc32fast", "criterion", "crypto_secretbox", "csv", diff --git a/Cargo.toml b/Cargo.toml index 8878a3014..47a2c3333 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,7 @@ stdlib = [ "dep:convert_case", "dep:cidr-utils", "dep:community-id", + "dep:crc32fast", "dep:crypto_secretbox", "dep:csv", "dep:ctr", @@ -134,6 +135,7 @@ csv = { version = "1", optional = true } clap = { version = "4", features = ["derive"], optional = true } codespan-reporting = {version = "0.11", optional = true } convert_case = { version = "0.6.0", optional = true } +crc32fast = {version = "1.4.2", optional = true} data-encoding = { version = "2", optional = true } digest = { version = "0.10", optional = true } dyn-clone = { version = "1", default-features = false, optional = true } diff --git a/benches/stdlib.rs b/benches/stdlib.rs index 441bf29c2..ff013ac62 100644 --- a/benches/stdlib.rs +++ b/benches/stdlib.rs @@ -23,6 +23,7 @@ criterion_group!( chunks, compact, contains, + crc32, decode_base16, decode_base64, decode_percent, @@ -286,6 +287,15 @@ bench_function! { } } +bench_function! { + crc32 => vrl::stdlib::Crc32; + + literal { + args: func_args![value: "foo"], + want: Ok("8c736521"), + } +} + bench_function! { decode_base16 => vrl::stdlib::DecodeBase16; diff --git a/src/stdlib/crc32.rs b/src/stdlib/crc32.rs new file mode 100644 index 000000000..27e9235c6 --- /dev/null +++ b/src/stdlib/crc32.rs @@ -0,0 +1,77 @@ +use crate::compiler::prelude::*; +use crc32fast::Hasher; + +fn crc32(value: Value) -> Resolved { + let value = value.try_bytes()?; + let mut hasher = Hasher::new(); + hasher.update(&value); + Ok(format!("{:x}", hasher.finalize()).into()) +} + +#[derive(Clone, Copy, Debug)] +pub struct Crc32; + +impl Function for Crc32 { + fn identifier(&self) -> &'static str { + "crc32" + } + + fn parameters(&self) -> &'static [Parameter] { + &[Parameter { + keyword: "value", + kind: kind::ANY, + required: true, + }] + } + + fn examples(&self) -> &'static [Example] { + &[Example { + title: "crc32", + source: r#"crc32("foobar")"#, + result: Ok("9ef61f95"), + }] + } + + fn compile( + &self, + _state: &state::TypeState, + _ctx: &mut FunctionCompileContext, + arguments: ArgumentList, + ) -> Compiled { + let value = arguments.required("value"); + + Ok(Crc32Fn { value }.as_expr()) + } +} + +#[derive(Debug, Clone)] +struct Crc32Fn { + value: Box, +} + +impl FunctionExpression for Crc32Fn { + fn resolve(&self, ctx: &mut Context) -> Resolved { + let value = self.value.resolve(ctx)?; + crc32(value) + } + + fn type_def(&self, _: &state::TypeState) -> TypeDef { + TypeDef::bytes().infallible() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::value; + + test_function![ + crc32 => Crc32; + + crc32 { + args: func_args![value: "foo"], + want: Ok(value!("8c736521")), + tdef: TypeDef::bytes().infallible(), + } + ]; +} diff --git a/src/stdlib/mod.rs b/src/stdlib/mod.rs index acc5f9653..703048c10 100644 --- a/src/stdlib/mod.rs +++ b/src/stdlib/mod.rs @@ -49,6 +49,7 @@ cfg_if::cfg_if! { mod compact; mod contains; mod contains_all; + mod crc32; mod decode_base16; mod decode_base64; mod decode_gzip; @@ -394,6 +395,7 @@ cfg_if::cfg_if! { pub use self::md5::Md5; pub use self::seahash::Seahash; pub use self::sha1::Sha1; + pub use self::crc32::Crc32; } } @@ -413,6 +415,7 @@ pub fn all() -> Vec> { Box::new(Compact), Box::new(Contains), Box::new(ContainsAll), + Box::new(Crc32), Box::new(DecodeBase16), Box::new(DecodeBase64), Box::new(DecodeGzip), From 3325ebf2fa119445e18bb5b0c6fa5b40352a16ad Mon Sep 17 00:00:00 2001 From: Ivor D'Souza Date: Tue, 10 Dec 2024 22:42:16 +0000 Subject: [PATCH 2/6] add algorithm param to crc function --- Cargo.lock | 21 +- Cargo.toml | 4 +- LICENSE-3rdparty.csv | 2 + benches/stdlib.rs | 4 +- src/stdlib/crc.rs | 587 +++++++++++++++++++++++++++++++++++++++++++ src/stdlib/crc32.rs | 77 ------ src/stdlib/mod.rs | 6 +- 7 files changed, 614 insertions(+), 87 deletions(-) create mode 100644 src/stdlib/crc.rs delete mode 100644 src/stdlib/crc32.rs diff --git a/Cargo.lock b/Cargo.lock index d119efb92..70c11ce26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -743,6 +743,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -2404,7 +2419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.13.0", "proc-macro2", "quote", "syn 2.0.90", @@ -3609,7 +3624,7 @@ dependencies = [ "codespan-reporting", "community-id", "convert_case 0.6.0", - "crc32fast", + "crc", "criterion", "crypto_secretbox", "csv", @@ -3878,7 +3893,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 74df91c3d..c17771160 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,7 @@ stdlib = [ "dep:convert_case", "dep:cidr-utils", "dep:community-id", - "dep:crc32fast", + "dep:crc", "dep:crypto_secretbox", "dep:csv", "dep:ctr", @@ -136,7 +136,7 @@ csv = { version = "1", optional = true } clap = { version = "4", features = ["derive"], optional = true } codespan-reporting = { version = "0.11", optional = true } convert_case = { version = "0.6.0", optional = true } -crc32fast = {version = "1.4.2", optional = true} +crc = { version = "3.2.1", optional = true } data-encoding = { version = "2", optional = true } digest = { version = "0.10", optional = true } dyn-clone = { version = "1", default-features = false, optional = true } diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 6948f382b..8d8d90059 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -62,6 +62,8 @@ convert_case,https://github.com/rutrum/convert-case,MIT,David Purdum core-foundation,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers cpufeatures,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers +crc,https://github.com/mrhooray/crc-rs,MIT OR Apache-2.0,"Rui Hu , Akhil Velagapudi <4@4khil.com>" +crc-catalog,https://github.com/akhilles/crc-catalog,MIT OR Apache-2.0,"Akhil Velagapudi " crc32fast,https://github.com/srijs/rust-crc32fast,MIT OR Apache-2.0,"Sam Rijs , Alex Crichton " crossbeam-channel,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-channel Authors crossbeam-epoch,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-epoch Authors diff --git a/benches/stdlib.rs b/benches/stdlib.rs index 599e4344d..4c84ed2b2 100644 --- a/benches/stdlib.rs +++ b/benches/stdlib.rs @@ -24,7 +24,7 @@ criterion_group!( community_id, compact, contains, - crc32, + crc, decode_base16, decode_base64, decode_charset, @@ -292,7 +292,7 @@ bench_function! { } bench_function! { - crc32 => vrl::stdlib::Crc32; + crc => vrl::stdlib::Crc; literal { args: func_args![value: "foo"], diff --git a/src/stdlib/crc.rs b/src/stdlib/crc.rs new file mode 100644 index 000000000..25e67d312 --- /dev/null +++ b/src/stdlib/crc.rs @@ -0,0 +1,587 @@ +use crate::compiler::prelude::*; +use crate::value; +use crc::Crc as CrcInstance; + +fn crc(value: Value, algorithm: Value) -> Resolved { + let value = value.try_bytes()?; + let algorithm = algorithm.try_bytes_utf8_lossy()?.as_ref().to_uppercase(); + + let checksum = match algorithm.as_str() { + "CRC_3_GSM" => CrcInstance::::new(&crc::CRC_3_GSM) + .checksum(&value) + .to_string(), + "CRC_3_ROHC" => CrcInstance::::new(&crc::CRC_3_ROHC) + .checksum(&value) + .to_string(), + "CRC_4_G_704" => CrcInstance::::new(&crc::CRC_4_G_704) + .checksum(&value) + .to_string(), + "CRC_4_INTERLAKEN" => CrcInstance::::new(&crc::CRC_4_INTERLAKEN) + .checksum(&value) + .to_string(), + "CRC_5_EPC_C1G2" => CrcInstance::::new(&crc::CRC_5_EPC_C1G2) + .checksum(&value) + .to_string(), + "CRC_5_G_704" => CrcInstance::::new(&crc::CRC_5_G_704) + .checksum(&value) + .to_string(), + "CRC_5_USB" => CrcInstance::::new(&crc::CRC_5_USB) + .checksum(&value) + .to_string(), + "CRC_6_CDMA2000_A" => CrcInstance::::new(&crc::CRC_6_CDMA2000_A) + .checksum(&value) + .to_string(), + "CRC_6_CDMA2000_B" => CrcInstance::::new(&crc::CRC_6_CDMA2000_B) + .checksum(&value) + .to_string(), + "CRC_6_DARC" => CrcInstance::::new(&crc::CRC_6_DARC) + .checksum(&value) + .to_string(), + "CRC_6_GSM" => CrcInstance::::new(&crc::CRC_6_GSM) + .checksum(&value) + .to_string(), + "CRC_6_G_704" => CrcInstance::::new(&crc::CRC_6_G_704) + .checksum(&value) + .to_string(), + "CRC_7_MMC" => CrcInstance::::new(&crc::CRC_7_MMC) + .checksum(&value) + .to_string(), + "CRC_7_ROHC" => CrcInstance::::new(&crc::CRC_7_ROHC) + .checksum(&value) + .to_string(), + "CRC_7_UMTS" => CrcInstance::::new(&crc::CRC_7_UMTS) + .checksum(&value) + .to_string(), + "CRC_8_AUTOSAR" => CrcInstance::::new(&crc::CRC_8_AUTOSAR) + .checksum(&value) + .to_string(), + "CRC_8_BLUETOOTH" => CrcInstance::::new(&crc::CRC_8_BLUETOOTH) + .checksum(&value) + .to_string(), + "CRC_8_CDMA2000" => CrcInstance::::new(&crc::CRC_8_CDMA2000) + .checksum(&value) + .to_string(), + "CRC_8_DARC" => CrcInstance::::new(&crc::CRC_8_DARC) + .checksum(&value) + .to_string(), + "CRC_8_DVB_S2" => CrcInstance::::new(&crc::CRC_8_DVB_S2) + .checksum(&value) + .to_string(), + "CRC_8_GSM_A" => CrcInstance::::new(&crc::CRC_8_GSM_A) + .checksum(&value) + .to_string(), + "CRC_8_GSM_B" => CrcInstance::::new(&crc::CRC_8_GSM_B) + .checksum(&value) + .to_string(), + "CRC_8_HITAG" => CrcInstance::::new(&crc::CRC_8_HITAG) + .checksum(&value) + .to_string(), + "CRC_8_I_432_1" => CrcInstance::::new(&crc::CRC_8_I_432_1) + .checksum(&value) + .to_string(), + "CRC_8_I_CODE" => CrcInstance::::new(&crc::CRC_8_I_CODE) + .checksum(&value) + .to_string(), + "CRC_8_LTE" => CrcInstance::::new(&crc::CRC_8_LTE) + .checksum(&value) + .to_string(), + "CRC_8_MAXIM_DOW" => CrcInstance::::new(&crc::CRC_8_MAXIM_DOW) + .checksum(&value) + .to_string(), + "CRC_8_MIFARE_MAD" => CrcInstance::::new(&crc::CRC_8_MIFARE_MAD) + .checksum(&value) + .to_string(), + "CRC_8_NRSC_5" => CrcInstance::::new(&crc::CRC_8_NRSC_5) + .checksum(&value) + .to_string(), + "CRC_8_OPENSAFETY" => CrcInstance::::new(&crc::CRC_8_OPENSAFETY) + .checksum(&value) + .to_string(), + "CRC_8_ROHC" => CrcInstance::::new(&crc::CRC_8_ROHC) + .checksum(&value) + .to_string(), + "CRC_8_SAE_J1850" => CrcInstance::::new(&crc::CRC_8_SAE_J1850) + .checksum(&value) + .to_string(), + "CRC_8_SMBUS" => CrcInstance::::new(&crc::CRC_8_SMBUS) + .checksum(&value) + .to_string(), + "CRC_8_TECH_3250" => CrcInstance::::new(&crc::CRC_8_TECH_3250) + .checksum(&value) + .to_string(), + "CRC_8_WCDMA" => CrcInstance::::new(&crc::CRC_8_WCDMA) + .checksum(&value) + .to_string(), + "CRC_10_ATM" => CrcInstance::::new(&crc::CRC_10_ATM) + .checksum(&value) + .to_string(), + "CRC_10_CDMA2000" => CrcInstance::::new(&crc::CRC_10_CDMA2000) + .checksum(&value) + .to_string(), + "CRC_10_GSM" => CrcInstance::::new(&crc::CRC_10_GSM) + .checksum(&value) + .to_string(), + "CRC_11_FLEXRAY" => CrcInstance::::new(&crc::CRC_11_FLEXRAY) + .checksum(&value) + .to_string(), + "CRC_11_UMTS" => CrcInstance::::new(&crc::CRC_11_UMTS) + .checksum(&value) + .to_string(), + "CRC_12_CDMA2000" => CrcInstance::::new(&crc::CRC_12_CDMA2000) + .checksum(&value) + .to_string(), + "CRC_12_DECT" => CrcInstance::::new(&crc::CRC_12_DECT) + .checksum(&value) + .to_string(), + "CRC_12_GSM" => CrcInstance::::new(&crc::CRC_12_GSM) + .checksum(&value) + .to_string(), + "CRC_12_UMTS" => CrcInstance::::new(&crc::CRC_12_UMTS) + .checksum(&value) + .to_string(), + "CRC_13_BBC" => CrcInstance::::new(&crc::CRC_13_BBC) + .checksum(&value) + .to_string(), + "CRC_14_DARC" => CrcInstance::::new(&crc::CRC_14_DARC) + .checksum(&value) + .to_string(), + "CRC_14_GSM" => CrcInstance::::new(&crc::CRC_14_GSM) + .checksum(&value) + .to_string(), + "CRC_15_CAN" => CrcInstance::::new(&crc::CRC_15_CAN) + .checksum(&value) + .to_string(), + "CRC_15_MPT1327" => CrcInstance::::new(&crc::CRC_15_MPT1327) + .checksum(&value) + .to_string(), + "CRC_16_ARC" => CrcInstance::::new(&crc::CRC_16_ARC) + .checksum(&value) + .to_string(), + "CRC_16_CDMA2000" => CrcInstance::::new(&crc::CRC_16_CDMA2000) + .checksum(&value) + .to_string(), + "CRC_16_CMS" => CrcInstance::::new(&crc::CRC_16_CMS) + .checksum(&value) + .to_string(), + "CRC_16_DDS_110" => CrcInstance::::new(&crc::CRC_16_DDS_110) + .checksum(&value) + .to_string(), + "CRC_16_DECT_R" => CrcInstance::::new(&crc::CRC_16_DECT_R) + .checksum(&value) + .to_string(), + "CRC_16_DECT_X" => CrcInstance::::new(&crc::CRC_16_DECT_X) + .checksum(&value) + .to_string(), + "CRC_16_DNP" => CrcInstance::::new(&crc::CRC_16_DNP) + .checksum(&value) + .to_string(), + "CRC_16_EN_13757" => CrcInstance::::new(&crc::CRC_16_EN_13757) + .checksum(&value) + .to_string(), + "CRC_16_GENIBUS" => CrcInstance::::new(&crc::CRC_16_GENIBUS) + .checksum(&value) + .to_string(), + "CRC_16_GSM" => CrcInstance::::new(&crc::CRC_16_GSM) + .checksum(&value) + .to_string(), + "CRC_16_IBM_3740" => CrcInstance::::new(&crc::CRC_16_IBM_3740) + .checksum(&value) + .to_string(), + "CRC_16_IBM_SDLC" => CrcInstance::::new(&crc::CRC_16_IBM_SDLC) + .checksum(&value) + .to_string(), + "CRC_16_ISO_IEC_14443_3_A" => CrcInstance::::new(&crc::CRC_16_ISO_IEC_14443_3_A) + .checksum(&value) + .to_string(), + "CRC_16_KERMIT" => CrcInstance::::new(&crc::CRC_16_KERMIT) + .checksum(&value) + .to_string(), + "CRC_16_LJ1200" => CrcInstance::::new(&crc::CRC_16_LJ1200) + .checksum(&value) + .to_string(), + "CRC_16_M17" => CrcInstance::::new(&crc::CRC_16_M17) + .checksum(&value) + .to_string(), + "CRC_16_MAXIM_DOW" => CrcInstance::::new(&crc::CRC_16_MAXIM_DOW) + .checksum(&value) + .to_string(), + "CRC_16_MCRF4XX" => CrcInstance::::new(&crc::CRC_16_MCRF4XX) + .checksum(&value) + .to_string(), + "CRC_16_MODBUS" => CrcInstance::::new(&crc::CRC_16_MODBUS) + .checksum(&value) + .to_string(), + "CRC_16_NRSC_5" => CrcInstance::::new(&crc::CRC_16_NRSC_5) + .checksum(&value) + .to_string(), + "CRC_16_OPENSAFETY_A" => CrcInstance::::new(&crc::CRC_16_OPENSAFETY_A) + .checksum(&value) + .to_string(), + "CRC_16_OPENSAFETY_B" => CrcInstance::::new(&crc::CRC_16_OPENSAFETY_B) + .checksum(&value) + .to_string(), + "CRC_16_PROFIBUS" => CrcInstance::::new(&crc::CRC_16_PROFIBUS) + .checksum(&value) + .to_string(), + "CRC_16_RIELLO" => CrcInstance::::new(&crc::CRC_16_RIELLO) + .checksum(&value) + .to_string(), + "CRC_16_SPI_FUJITSU" => CrcInstance::::new(&crc::CRC_16_SPI_FUJITSU) + .checksum(&value) + .to_string(), + "CRC_16_T10_DIF" => CrcInstance::::new(&crc::CRC_16_T10_DIF) + .checksum(&value) + .to_string(), + "CRC_16_TELEDISK" => CrcInstance::::new(&crc::CRC_16_TELEDISK) + .checksum(&value) + .to_string(), + "CRC_16_TMS37157" => CrcInstance::::new(&crc::CRC_16_TMS37157) + .checksum(&value) + .to_string(), + "CRC_16_UMTS" => CrcInstance::::new(&crc::CRC_16_UMTS) + .checksum(&value) + .to_string(), + "CRC_16_USB" => CrcInstance::::new(&crc::CRC_16_USB) + .checksum(&value) + .to_string(), + "CRC_16_XMODEM" => CrcInstance::::new(&crc::CRC_16_XMODEM) + .checksum(&value) + .to_string(), + "CRC_17_CAN_FD" => CrcInstance::::new(&crc::CRC_17_CAN_FD) + .checksum(&value) + .to_string(), + "CRC_21_CAN_FD" => CrcInstance::::new(&crc::CRC_21_CAN_FD) + .checksum(&value) + .to_string(), + "CRC_24_BLE" => CrcInstance::::new(&crc::CRC_24_BLE) + .checksum(&value) + .to_string(), + "CRC_24_FLEXRAY_A" => CrcInstance::::new(&crc::CRC_24_FLEXRAY_A) + .checksum(&value) + .to_string(), + "CRC_24_FLEXRAY_B" => CrcInstance::::new(&crc::CRC_24_FLEXRAY_B) + .checksum(&value) + .to_string(), + "CRC_24_INTERLAKEN" => CrcInstance::::new(&crc::CRC_24_INTERLAKEN) + .checksum(&value) + .to_string(), + "CRC_24_LTE_A" => CrcInstance::::new(&crc::CRC_24_LTE_A) + .checksum(&value) + .to_string(), + "CRC_24_LTE_B" => CrcInstance::::new(&crc::CRC_24_LTE_B) + .checksum(&value) + .to_string(), + "CRC_24_OPENPGP" => CrcInstance::::new(&crc::CRC_24_OPENPGP) + .checksum(&value) + .to_string(), + "CRC_24_OS_9" => CrcInstance::::new(&crc::CRC_24_OS_9) + .checksum(&value) + .to_string(), + "CRC_30_CDMA" => CrcInstance::::new(&crc::CRC_30_CDMA) + .checksum(&value) + .to_string(), + "CRC_31_PHILIPS" => CrcInstance::::new(&crc::CRC_31_PHILIPS) + .checksum(&value) + .to_string(), + "CRC_32_AIXM" => CrcInstance::::new(&crc::CRC_32_AIXM) + .checksum(&value) + .to_string(), + "CRC_32_AUTOSAR" => CrcInstance::::new(&crc::CRC_32_AUTOSAR) + .checksum(&value) + .to_string(), + "CRC_32_BASE91_D" => CrcInstance::::new(&crc::CRC_32_BASE91_D) + .checksum(&value) + .to_string(), + "CRC_32_BZIP2" => CrcInstance::::new(&crc::CRC_32_BZIP2) + .checksum(&value) + .to_string(), + "CRC_32_CD_ROM_EDC" => CrcInstance::::new(&crc::CRC_32_CD_ROM_EDC) + .checksum(&value) + .to_string(), + "CRC_32_CKSUM" => CrcInstance::::new(&crc::CRC_32_CKSUM) + .checksum(&value) + .to_string(), + "CRC_32_ISCSI" => CrcInstance::::new(&crc::CRC_32_ISCSI) + .checksum(&value) + .to_string(), + "CRC_32_ISO_HDLC" => CrcInstance::::new(&crc::CRC_32_ISO_HDLC) + .checksum(&value) + .to_string(), + "CRC_32_JAMCRC" => CrcInstance::::new(&crc::CRC_32_JAMCRC) + .checksum(&value) + .to_string(), + "CRC_32_MEF" => CrcInstance::::new(&crc::CRC_32_MEF) + .checksum(&value) + .to_string(), + "CRC_32_MPEG_2" => CrcInstance::::new(&crc::CRC_32_MPEG_2) + .checksum(&value) + .to_string(), + "CRC_32_XFER" => CrcInstance::::new(&crc::CRC_32_XFER) + .checksum(&value) + .to_string(), + "CRC_40_GSM" => CrcInstance::::new(&crc::CRC_40_GSM) + .checksum(&value) + .to_string(), + "CRC_64_ECMA_182" => CrcInstance::::new(&crc::CRC_64_ECMA_182) + .checksum(&value) + .to_string(), + "CRC_64_GO_ISO" => CrcInstance::::new(&crc::CRC_64_GO_ISO) + .checksum(&value) + .to_string(), + "CRC_64_MS" => CrcInstance::::new(&crc::CRC_64_MS) + .checksum(&value) + .to_string(), + "CRC_64_REDIS" => CrcInstance::::new(&crc::CRC_64_REDIS) + .checksum(&value) + .to_string(), + "CRC_64_WE" => CrcInstance::::new(&crc::CRC_64_WE) + .checksum(&value) + .to_string(), + "CRC_64_XZ" => CrcInstance::::new(&crc::CRC_64_XZ) + .checksum(&value) + .to_string(), + "CRC_82_DARC" => CrcInstance::::new(&crc::CRC_82_DARC) + .checksum(&value) + .to_string(), + _ => return Err(format!("Invalid CRC algorithm: {algorithm}").into()), + }; + + Ok(checksum.into()) +} + +#[derive(Clone, Copy, Debug)] +pub struct Crc; + +impl Function for Crc { + fn identifier(&self) -> &'static str { + "crc" + } + + fn parameters(&self) -> &'static [Parameter] { + &[ + Parameter { + keyword: "value", + kind: kind::BYTES, + required: true, + }, + Parameter { + keyword: "algorithm", + kind: kind::BYTES, + required: false, + }, + ] + } + + fn examples(&self) -> &'static [Example] { + &[ + Example { + title: "default CRC_32_ISO_HDLC", + source: r#"encode_base64(crc("foobar"))"#, + result: Ok("MjY2NjkzMDA2OQ=="), + }, + Example { + title: "CRC_8_MAXIM_DOW", + source: r#"encode_base64(crc("foobar", algorithm: "CRC_8_MAXIM_DOW"))"#, + result: Ok("NTM="), + }, + ] + } + + fn compile( + &self, + _state: &state::TypeState, + _ctx: &mut FunctionCompileContext, + arguments: ArgumentList, + ) -> Compiled { + let value = arguments.required("value"); + let algorithm = arguments.optional("algorithm"); + + Ok(CrcFn { value, algorithm }.as_expr()) + } +} + +#[derive(Debug, Clone)] +struct CrcFn { + value: Box, + algorithm: Option>, +} + +impl FunctionExpression for CrcFn { + fn resolve(&self, ctx: &mut Context) -> Resolved { + let value = self.value.resolve(ctx)?; + let algorithm = match &self.algorithm { + Some(algorithm) => algorithm.resolve(ctx)?, + None => value!("CRC_32_ISO_HDLC"), + }; + + crc(value, algorithm) + } + + fn type_def(&self, state: &state::TypeState) -> TypeDef { + let valid_algorithms = [ + "CRC_3_GSM", + "CRC_3_ROHC", + "CRC_4_G_704", + "CRC_4_INTERLAKEN", + "CRC_5_EPC_C1G2", + "CRC_5_G_704", + "CRC_5_USB", + "CRC_6_CDMA2000_A", + "CRC_6_CDMA2000_B", + "CRC_6_DARC", + "CRC_6_GSM", + "CRC_6_G_704", + "CRC_7_MMC", + "CRC_7_ROHC", + "CRC_7_UMTS", + "CRC_8_AUTOSAR", + "CRC_8_BLUETOOTH", + "CRC_8_CDMA2000", + "CRC_8_DARC", + "CRC_8_DVB_S2", + "CRC_8_GSM_A", + "CRC_8_GSM_B", + "CRC_8_HITAG", + "CRC_8_I_432_1", + "CRC_8_I_CODE", + "CRC_8_LTE", + "CRC_8_MAXIM_DOW", + "CRC_8_MIFARE_MAD", + "CRC_8_NRSC_5", + "CRC_8_OPENSAFETY", + "CRC_8_ROHC", + "CRC_8_SAE_J1850", + "CRC_8_SMBUS", + "CRC_8_TECH_3250", + "CRC_8_WCDMA", + "CRC_10_ATM", + "CRC_10_CDMA2000", + "CRC_10_GSM", + "CRC_11_FLEXRAY", + "CRC_11_UMTS", + "CRC_12_CDMA2000", + "CRC_12_DECT", + "CRC_12_GSM", + "CRC_12_UMTS", + "CRC_13_BBC", + "CRC_14_DARC", + "CRC_14_GSM", + "CRC_15_CAN", + "CRC_15_MPT1327", + "CRC_16_ARC", + "CRC_16_CDMA2000", + "CRC_16_CMS", + "CRC_16_DDS_110", + "CRC_16_DECT_R", + "CRC_16_DECT_X", + "CRC_16_DNP", + "CRC_16_EN_13757", + "CRC_16_GENIBUS", + "CRC_16_GSM", + "CRC_16_IBM_3740", + "CRC_16_IBM_SDLC", + "CRC_16_ISO_IEC_14443_3_A", + "CRC_16_KERMIT", + "CRC_16_LJ1200", + "CRC_16_M17", + "CRC_16_MAXIM_DOW", + "CRC_16_MCRF4XX", + "CRC_16_MODBUS", + "CRC_16_NRSC_5", + "CRC_16_OPENSAFETY_A", + "CRC_16_OPENSAFETY_B", + "CRC_16_PROFIBUS", + "CRC_16_RIELLO", + "CRC_16_SPI_FUJITSU", + "CRC_16_T10_DIF", + "CRC_16_TELEDISK", + "CRC_16_TMS37157", + "CRC_16_UMTS", + "CRC_16_USB", + "CRC_16_XMODEM", + "CRC_17_CAN_FD", + "CRC_21_CAN_FD", + "CRC_24_BLE", + "CRC_24_FLEXRAY_A", + "CRC_24_FLEXRAY_B", + "CRC_24_INTERLAKEN", + "CRC_24_LTE_A", + "CRC_24_LTE_B", + "CRC_24_OPENPGP", + "CRC_24_OS_9", + "CRC_30_CDMA", + "CRC_31_PHILIPS", + "CRC_32_AIXM", + "CRC_32_AUTOSAR", + "CRC_32_BASE91_D", + "CRC_32_BZIP2", + "CRC_32_CD_ROM_EDC", + "CRC_32_CKSUM", + "CRC_32_ISCSI", + "CRC_32_ISO_HDLC", + "CRC_32_JAMCRC", + "CRC_32_MEF", + "CRC_32_MPEG_2", + "CRC_32_XFER", + "CRC_40_GSM", + "CRC_64_ECMA_182", + "CRC_64_GO_ISO", + "CRC_64_MS", + "CRC_64_REDIS", + "CRC_64_WE", + "CRC_64_XZ", + "CRC_82_DARC", + ]; + + let mut valid_static_algo = false; + if let Some(algorithm) = self.algorithm.as_ref() { + if let Some(algorithm) = algorithm.resolve_constant(state) { + if let Ok(algorithm) = algorithm.try_bytes_utf8_lossy() { + let algorithm = algorithm.to_uppercase(); + valid_static_algo = valid_algorithms.contains(&algorithm.as_str()); + } + } + } else { + valid_static_algo = true + } + + if valid_static_algo { + TypeDef::bytes().infallible() + } else { + TypeDef::bytes().fallible() + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + test_function![ + crc => Crc; + + crc_default { + args: func_args![value: "foo"], + want: Ok(value!(b"2356372769")), + tdef: TypeDef::bytes().infallible(), + } + + crc_crc8 { + args: func_args![value: "foo", algorithm: "CRC_8_MAXIM_DOW"], + want: Ok(value!(b"18")), + tdef: TypeDef::bytes().infallible(), + } + + crc_crc32 { + args: func_args![value: "foo", algorithm: "CRC_32_CKSUM"], + want: Ok(value!(b"4271552933")), + tdef: TypeDef::bytes().infallible(), + } + + crc_crc64 { + args: func_args![value: "foo", algorithm: "CRC_64_REDIS"], + want: Ok(value!(b"12626267673720558670")), + tdef: TypeDef::bytes().infallible(), + } + ]; +} diff --git a/src/stdlib/crc32.rs b/src/stdlib/crc32.rs deleted file mode 100644 index 27e9235c6..000000000 --- a/src/stdlib/crc32.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::compiler::prelude::*; -use crc32fast::Hasher; - -fn crc32(value: Value) -> Resolved { - let value = value.try_bytes()?; - let mut hasher = Hasher::new(); - hasher.update(&value); - Ok(format!("{:x}", hasher.finalize()).into()) -} - -#[derive(Clone, Copy, Debug)] -pub struct Crc32; - -impl Function for Crc32 { - fn identifier(&self) -> &'static str { - "crc32" - } - - fn parameters(&self) -> &'static [Parameter] { - &[Parameter { - keyword: "value", - kind: kind::ANY, - required: true, - }] - } - - fn examples(&self) -> &'static [Example] { - &[Example { - title: "crc32", - source: r#"crc32("foobar")"#, - result: Ok("9ef61f95"), - }] - } - - fn compile( - &self, - _state: &state::TypeState, - _ctx: &mut FunctionCompileContext, - arguments: ArgumentList, - ) -> Compiled { - let value = arguments.required("value"); - - Ok(Crc32Fn { value }.as_expr()) - } -} - -#[derive(Debug, Clone)] -struct Crc32Fn { - value: Box, -} - -impl FunctionExpression for Crc32Fn { - fn resolve(&self, ctx: &mut Context) -> Resolved { - let value = self.value.resolve(ctx)?; - crc32(value) - } - - fn type_def(&self, _: &state::TypeState) -> TypeDef { - TypeDef::bytes().infallible() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::value; - - test_function![ - crc32 => Crc32; - - crc32 { - args: func_args![value: "foo"], - want: Ok(value!("8c736521")), - tdef: TypeDef::bytes().infallible(), - } - ]; -} diff --git a/src/stdlib/mod.rs b/src/stdlib/mod.rs index b1c8575db..3df215194 100644 --- a/src/stdlib/mod.rs +++ b/src/stdlib/mod.rs @@ -49,7 +49,7 @@ cfg_if::cfg_if! { mod compact; mod contains; mod contains_all; - mod crc32; + mod crc; mod decode_base16; mod decode_base64; mod decode_charset; @@ -403,7 +403,7 @@ cfg_if::cfg_if! { pub use self::md5::Md5; pub use self::seahash::Seahash; pub use self::sha1::Sha1; - pub use self::crc32::Crc32; + pub use self::crc::Crc; } } @@ -423,7 +423,7 @@ pub fn all() -> Vec> { Box::new(Compact), Box::new(Contains), Box::new(ContainsAll), - Box::new(Crc32), + Box::new(Crc), Box::new(DecodeBase16), Box::new(DecodeBase64), Box::new(DecodeCharset), From cebdcb1f4bcb693113c8f2495c6c5b4f2574da19 Mon Sep 17 00:00:00 2001 From: Ivor D'Souza Date: Tue, 10 Dec 2024 23:03:22 +0000 Subject: [PATCH 3/6] update bench_function for crc --- benches/stdlib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benches/stdlib.rs b/benches/stdlib.rs index 4c84ed2b2..c0da0309f 100644 --- a/benches/stdlib.rs +++ b/benches/stdlib.rs @@ -296,7 +296,7 @@ bench_function! { literal { args: func_args![value: "foo"], - want: Ok("8c736521"), + want: Ok(b"2356372769"), } } From 54ad18467cfc5e7b9e2724c95e3e5ab5f82b2f67 Mon Sep 17 00:00:00 2001 From: Ivor D'Souza Date: Wed, 11 Dec 2024 13:50:10 +0000 Subject: [PATCH 4/6] remove base64 encode from example crc usage --- src/stdlib/crc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stdlib/crc.rs b/src/stdlib/crc.rs index 25e67d312..5d79a100d 100644 --- a/src/stdlib/crc.rs +++ b/src/stdlib/crc.rs @@ -376,13 +376,13 @@ impl Function for Crc { &[ Example { title: "default CRC_32_ISO_HDLC", - source: r#"encode_base64(crc("foobar"))"#, - result: Ok("MjY2NjkzMDA2OQ=="), + source: r#"crc("foobar")"#, + result: Ok(r#""2666930069""#), }, Example { title: "CRC_8_MAXIM_DOW", - source: r#"encode_base64(crc("foobar", algorithm: "CRC_8_MAXIM_DOW"))"#, - result: Ok("NTM="), + source: r#"crc("foobar", algorithm: "CRC_8_MAXIM_DOW")"#, + result: Ok(r#""53""#), }, ] } From df4bbc9597cad28e85a1d3c89b91088e7f362110 Mon Sep 17 00:00:00 2001 From: Ivor D'Souza Date: Thu, 12 Dec 2024 20:59:35 +0000 Subject: [PATCH 5/6] add invalid test case, code formatting --- LICENSE-3rdparty.csv | 2 +- src/stdlib/crc.rs | 255 ++++++++++++++++++++++--------------------- 2 files changed, 130 insertions(+), 127 deletions(-) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 8d8d90059..ba2fb3057 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -63,7 +63,7 @@ convert_case,https://github.com/rutrum/convert-case,MIT,Rutrum core-foundation,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers cpufeatures,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers crc,https://github.com/mrhooray/crc-rs,MIT OR Apache-2.0,"Rui Hu , Akhil Velagapudi <4@4khil.com>" -crc-catalog,https://github.com/akhilles/crc-catalog,MIT OR Apache-2.0,"Akhil Velagapudi " +crc-catalog,https://github.com/akhilles/crc-catalog,MIT OR Apache-2.0,Akhil Velagapudi crc32fast,https://github.com/srijs/rust-crc32fast,MIT OR Apache-2.0,"Sam Rijs , Alex Crichton " crossbeam-channel,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-channel Authors crossbeam-epoch,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-epoch Authors diff --git a/src/stdlib/crc.rs b/src/stdlib/crc.rs index 5d79a100d..02c7fa060 100644 --- a/src/stdlib/crc.rs +++ b/src/stdlib/crc.rs @@ -2,6 +2,121 @@ use crate::compiler::prelude::*; use crate::value; use crc::Crc as CrcInstance; +const VALID_ALGORITHMS: &[&str] = &[ + "CRC_3_GSM", + "CRC_3_ROHC", + "CRC_4_G_704", + "CRC_4_INTERLAKEN", + "CRC_5_EPC_C1G2", + "CRC_5_G_704", + "CRC_5_USB", + "CRC_6_CDMA2000_A", + "CRC_6_CDMA2000_B", + "CRC_6_DARC", + "CRC_6_GSM", + "CRC_6_G_704", + "CRC_7_MMC", + "CRC_7_ROHC", + "CRC_7_UMTS", + "CRC_8_AUTOSAR", + "CRC_8_BLUETOOTH", + "CRC_8_CDMA2000", + "CRC_8_DARC", + "CRC_8_DVB_S2", + "CRC_8_GSM_A", + "CRC_8_GSM_B", + "CRC_8_HITAG", + "CRC_8_I_432_1", + "CRC_8_I_CODE", + "CRC_8_LTE", + "CRC_8_MAXIM_DOW", + "CRC_8_MIFARE_MAD", + "CRC_8_NRSC_5", + "CRC_8_OPENSAFETY", + "CRC_8_ROHC", + "CRC_8_SAE_J1850", + "CRC_8_SMBUS", + "CRC_8_TECH_3250", + "CRC_8_WCDMA", + "CRC_10_ATM", + "CRC_10_CDMA2000", + "CRC_10_GSM", + "CRC_11_FLEXRAY", + "CRC_11_UMTS", + "CRC_12_CDMA2000", + "CRC_12_DECT", + "CRC_12_GSM", + "CRC_12_UMTS", + "CRC_13_BBC", + "CRC_14_DARC", + "CRC_14_GSM", + "CRC_15_CAN", + "CRC_15_MPT1327", + "CRC_16_ARC", + "CRC_16_CDMA2000", + "CRC_16_CMS", + "CRC_16_DDS_110", + "CRC_16_DECT_R", + "CRC_16_DECT_X", + "CRC_16_DNP", + "CRC_16_EN_13757", + "CRC_16_GENIBUS", + "CRC_16_GSM", + "CRC_16_IBM_3740", + "CRC_16_IBM_SDLC", + "CRC_16_ISO_IEC_14443_3_A", + "CRC_16_KERMIT", + "CRC_16_LJ1200", + "CRC_16_M17", + "CRC_16_MAXIM_DOW", + "CRC_16_MCRF4XX", + "CRC_16_MODBUS", + "CRC_16_NRSC_5", + "CRC_16_OPENSAFETY_A", + "CRC_16_OPENSAFETY_B", + "CRC_16_PROFIBUS", + "CRC_16_RIELLO", + "CRC_16_SPI_FUJITSU", + "CRC_16_T10_DIF", + "CRC_16_TELEDISK", + "CRC_16_TMS37157", + "CRC_16_UMTS", + "CRC_16_USB", + "CRC_16_XMODEM", + "CRC_17_CAN_FD", + "CRC_21_CAN_FD", + "CRC_24_BLE", + "CRC_24_FLEXRAY_A", + "CRC_24_FLEXRAY_B", + "CRC_24_INTERLAKEN", + "CRC_24_LTE_A", + "CRC_24_LTE_B", + "CRC_24_OPENPGP", + "CRC_24_OS_9", + "CRC_30_CDMA", + "CRC_31_PHILIPS", + "CRC_32_AIXM", + "CRC_32_AUTOSAR", + "CRC_32_BASE91_D", + "CRC_32_BZIP2", + "CRC_32_CD_ROM_EDC", + "CRC_32_CKSUM", + "CRC_32_ISCSI", + "CRC_32_ISO_HDLC", + "CRC_32_JAMCRC", + "CRC_32_MEF", + "CRC_32_MPEG_2", + "CRC_32_XFER", + "CRC_40_GSM", + "CRC_64_ECMA_182", + "CRC_64_GO_ISO", + "CRC_64_MS", + "CRC_64_REDIS", + "CRC_64_WE", + "CRC_64_XZ", + "CRC_82_DARC", +]; + fn crc(value: Value, algorithm: Value) -> Resolved { let value = value.try_bytes()?; let algorithm = algorithm.try_bytes_utf8_lossy()?.as_ref().to_uppercase(); @@ -418,132 +533,14 @@ impl FunctionExpression for CrcFn { } fn type_def(&self, state: &state::TypeState) -> TypeDef { - let valid_algorithms = [ - "CRC_3_GSM", - "CRC_3_ROHC", - "CRC_4_G_704", - "CRC_4_INTERLAKEN", - "CRC_5_EPC_C1G2", - "CRC_5_G_704", - "CRC_5_USB", - "CRC_6_CDMA2000_A", - "CRC_6_CDMA2000_B", - "CRC_6_DARC", - "CRC_6_GSM", - "CRC_6_G_704", - "CRC_7_MMC", - "CRC_7_ROHC", - "CRC_7_UMTS", - "CRC_8_AUTOSAR", - "CRC_8_BLUETOOTH", - "CRC_8_CDMA2000", - "CRC_8_DARC", - "CRC_8_DVB_S2", - "CRC_8_GSM_A", - "CRC_8_GSM_B", - "CRC_8_HITAG", - "CRC_8_I_432_1", - "CRC_8_I_CODE", - "CRC_8_LTE", - "CRC_8_MAXIM_DOW", - "CRC_8_MIFARE_MAD", - "CRC_8_NRSC_5", - "CRC_8_OPENSAFETY", - "CRC_8_ROHC", - "CRC_8_SAE_J1850", - "CRC_8_SMBUS", - "CRC_8_TECH_3250", - "CRC_8_WCDMA", - "CRC_10_ATM", - "CRC_10_CDMA2000", - "CRC_10_GSM", - "CRC_11_FLEXRAY", - "CRC_11_UMTS", - "CRC_12_CDMA2000", - "CRC_12_DECT", - "CRC_12_GSM", - "CRC_12_UMTS", - "CRC_13_BBC", - "CRC_14_DARC", - "CRC_14_GSM", - "CRC_15_CAN", - "CRC_15_MPT1327", - "CRC_16_ARC", - "CRC_16_CDMA2000", - "CRC_16_CMS", - "CRC_16_DDS_110", - "CRC_16_DECT_R", - "CRC_16_DECT_X", - "CRC_16_DNP", - "CRC_16_EN_13757", - "CRC_16_GENIBUS", - "CRC_16_GSM", - "CRC_16_IBM_3740", - "CRC_16_IBM_SDLC", - "CRC_16_ISO_IEC_14443_3_A", - "CRC_16_KERMIT", - "CRC_16_LJ1200", - "CRC_16_M17", - "CRC_16_MAXIM_DOW", - "CRC_16_MCRF4XX", - "CRC_16_MODBUS", - "CRC_16_NRSC_5", - "CRC_16_OPENSAFETY_A", - "CRC_16_OPENSAFETY_B", - "CRC_16_PROFIBUS", - "CRC_16_RIELLO", - "CRC_16_SPI_FUJITSU", - "CRC_16_T10_DIF", - "CRC_16_TELEDISK", - "CRC_16_TMS37157", - "CRC_16_UMTS", - "CRC_16_USB", - "CRC_16_XMODEM", - "CRC_17_CAN_FD", - "CRC_21_CAN_FD", - "CRC_24_BLE", - "CRC_24_FLEXRAY_A", - "CRC_24_FLEXRAY_B", - "CRC_24_INTERLAKEN", - "CRC_24_LTE_A", - "CRC_24_LTE_B", - "CRC_24_OPENPGP", - "CRC_24_OS_9", - "CRC_30_CDMA", - "CRC_31_PHILIPS", - "CRC_32_AIXM", - "CRC_32_AUTOSAR", - "CRC_32_BASE91_D", - "CRC_32_BZIP2", - "CRC_32_CD_ROM_EDC", - "CRC_32_CKSUM", - "CRC_32_ISCSI", - "CRC_32_ISO_HDLC", - "CRC_32_JAMCRC", - "CRC_32_MEF", - "CRC_32_MPEG_2", - "CRC_32_XFER", - "CRC_40_GSM", - "CRC_64_ECMA_182", - "CRC_64_GO_ISO", - "CRC_64_MS", - "CRC_64_REDIS", - "CRC_64_WE", - "CRC_64_XZ", - "CRC_82_DARC", - ]; - - let mut valid_static_algo = false; - if let Some(algorithm) = self.algorithm.as_ref() { - if let Some(algorithm) = algorithm.resolve_constant(state) { - if let Ok(algorithm) = algorithm.try_bytes_utf8_lossy() { - let algorithm = algorithm.to_uppercase(); - valid_static_algo = valid_algorithms.contains(&algorithm.as_str()); - } - } - } else { - valid_static_algo = true - } + let algorithm = self.algorithm.as_ref(); + let valid_static_algo = algorithm.is_none() + || algorithm + .and_then(|algorithm| algorithm.resolve_constant(state)) + .and_then(|algorithm| algorithm.try_bytes_utf8_lossy().map(|s| s.to_string()).ok()) + .is_some_and(|algorithm| { + VALID_ALGORITHMS.contains(&algorithm.to_uppercase().as_str()) + }); if valid_static_algo { TypeDef::bytes().infallible() @@ -583,5 +580,11 @@ mod tests { want: Ok(value!(b"12626267673720558670")), tdef: TypeDef::bytes().infallible(), } + + crc_unknown { + args: func_args![value: "foo", algorithm: "CRC_UNKNOWN"], + want: Err("Invalid CRC algorithm: CRC_UNKNOWN"), + tdef: TypeDef::bytes().fallible(), + } ]; } From 2d58fe230005a80f99a87129cbc401cebd960e71 Mon Sep 17 00:00:00 2001 From: Ivor D'Souza Date: Sat, 14 Dec 2024 23:08:57 +0000 Subject: [PATCH 6/6] add changelog --- changelog.d/1136.feature.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog.d/1136.feature.md diff --git a/changelog.d/1136.feature.md b/changelog.d/1136.feature.md new file mode 100644 index 000000000..35f02627d --- /dev/null +++ b/changelog.d/1136.feature.md @@ -0,0 +1,3 @@ +Added new `crc` function to calculate CRC (Cyclic Redundancy Check) checksum + +authors: ivor11 \ No newline at end of file