Merge pull request #151 from evrins/bugfix/fix_base32_encoded_magnet
fix: can not add base32 encoded magnet url
This commit is contained in:
commit
7820bcf053
3 changed files with 46 additions and 7 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -618,6 +618,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
|
|
@ -1364,6 +1370,7 @@ name = "librqbit-core"
|
|||
version = "3.8.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"data-encoding",
|
||||
"directories",
|
||||
"hex 0.4.3",
|
||||
"itertools",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ clone_to_owned = { path = "../clone_to_owned", package = "librqbit-clone-to-owne
|
|||
itertools = "0.12"
|
||||
directories = "5"
|
||||
tokio-util = "0.7.10"
|
||||
data-encoding = "2.6.0"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{cmp::Ordering, str::FromStr};
|
||||
|
||||
use data_encoding::BASE32;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::{cmp::Ordering, str::FromStr};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Id<const N: usize>(pub [u8; N]);
|
||||
|
|
@ -69,11 +69,32 @@ impl<const N: usize> FromStr for Id<N> {
|
|||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut out = [0u8; N];
|
||||
if s.len() != N * 2 {
|
||||
anyhow::bail!("expected a hex string of length {}", N * 2)
|
||||
};
|
||||
hex::decode_to_slice(s, &mut out)?;
|
||||
Ok(Id(out))
|
||||
let base32_encoded_size = (N as f64 / 5f64).ceil() as usize * 8;
|
||||
if s.len() == N * 2 {
|
||||
hex::decode_to_slice(s, &mut out)?;
|
||||
Ok(Id(out))
|
||||
// try decode as base32
|
||||
} else if s.len() == base32_encoded_size {
|
||||
match BASE32.decode(s.as_bytes()) {
|
||||
Ok(decoded) => {
|
||||
out.copy_from_slice(&decoded);
|
||||
Ok(Id(out))
|
||||
}
|
||||
Err(err) => {
|
||||
anyhow::bail!(
|
||||
"fail to decode base32 string {}: {}",
|
||||
s,
|
||||
err
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
anyhow::bail!(
|
||||
"expected a hex string of length {} or {}",
|
||||
N * 2,
|
||||
base32_encoded_size
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,4 +205,13 @@ mod tests {
|
|||
let str = "06f04cc728bef957a658876ef807f0514e4d715392969998efef584d2c3e435e";
|
||||
let _ih = Id32::from_str(str).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id20_base32_encoded_from_str() {
|
||||
let str = "Z7QRDHYSJCA4U4HXGBXTFYUSDFGIRQMV";
|
||||
let ih1 = Id20::from_str(str).unwrap();
|
||||
let s2 = "cfe1119f124881ca70f7306f32e292194c88c195";
|
||||
let ih2 = Id20::from_str(s2).unwrap();
|
||||
assert_eq!(ih1, ih2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue