Move multibase encoder and decoder to utils::multibase

This commit is contained in:
silverpill 2022-11-18 22:58:58 +00:00
parent e1bb00a8dc
commit bd4a9a0de9
3 changed files with 55 additions and 38 deletions

View file

@ -4,6 +4,10 @@ use std::str::FromStr;
use regex::Regex; use regex::Regex;
use crate::utils::multibase::{
decode_multibase_base58btc,
encode_multibase_base58btc,
};
use super::did::DidParseError; use super::did::DidParseError;
const DID_KEY_RE: &str = r"did:key:(?P<key>z[a-km-zA-HJ-NP-Z1-9]+)"; const DID_KEY_RE: &str = r"did:key:(?P<key>z[a-km-zA-HJ-NP-Z1-9]+)";
@ -50,44 +54,6 @@ impl DidKey {
} }
} }
#[derive(thiserror::Error, Debug)]
enum MultibaseError {
#[error("invalid base string")]
InvalidBaseString,
#[error("unknown base")]
UnknownBase,
#[error(transparent)]
DecodeError(#[from] bs58::decode::Error),
}
/// Decodes multibase base58 (bitcoin) value
/// https://github.com/multiformats/multibase
fn decode_multibase_base58btc(value: &str)
-> Result<Vec<u8>, MultibaseError>
{
let base = value.chars().next()
.ok_or(MultibaseError::InvalidBaseString)?;
// z == base58btc
// https://github.com/multiformats/multibase#multibase-table
if base.to_string() != "z" {
return Err(MultibaseError::UnknownBase);
};
let encoded_data = &value[base.len_utf8()..];
let data = bs58::decode(encoded_data)
.with_alphabet(bs58::Alphabet::BITCOIN)
.into_vec()?;
Ok(data)
}
fn encode_multibase_base58btc(value: &[u8]) -> String {
let result = bs58::encode(value)
.with_alphabet(bs58::Alphabet::BITCOIN)
.into_string();
format!("z{}", result)
}
impl FromStr for DidKey { impl FromStr for DidKey {
type Err = DidParseError; type Err = DidParseError;

View file

@ -6,5 +6,6 @@ pub mod files;
pub mod html; pub mod html;
pub mod id; pub mod id;
pub mod markdown; pub mod markdown;
pub mod multibase;
pub mod passwords; pub mod passwords;
pub mod urls; pub mod urls;

50
src/utils/multibase.rs Normal file
View file

@ -0,0 +1,50 @@
#[derive(thiserror::Error, Debug)]
pub enum MultibaseError {
#[error("invalid base string")]
InvalidBaseString,
#[error("unknown base")]
UnknownBase,
#[error(transparent)]
DecodeError(#[from] bs58::decode::Error),
}
/// Decodes multibase base58 (bitcoin) value
/// https://github.com/multiformats/multibase
pub fn decode_multibase_base58btc(value: &str)
-> Result<Vec<u8>, MultibaseError>
{
let base = value.chars().next()
.ok_or(MultibaseError::InvalidBaseString)?;
// z == base58btc
// https://github.com/multiformats/multibase#multibase-table
if base.to_string() != "z" {
return Err(MultibaseError::UnknownBase);
};
let encoded_data = &value[base.len_utf8()..];
let data = bs58::decode(encoded_data)
.with_alphabet(bs58::Alphabet::BITCOIN)
.into_vec()?;
Ok(data)
}
pub fn encode_multibase_base58btc(value: &[u8]) -> String {
let result = bs58::encode(value)
.with_alphabet(bs58::Alphabet::BITCOIN)
.into_string();
format!("z{}", result)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_base58btc_encode_decode() {
let value = [1; 20];
let encoded = encode_multibase_base58btc(&value);
let decoded = decode_multibase_base58btc(&encoded).unwrap();
assert_eq!(decoded, value);
}
}