From de5236ea04611971929d433a7b69ceab792cd169 Mon Sep 17 00:00:00 2001 From: QuantumExplorer Date: Wed, 9 Oct 2024 13:09:39 +0700 Subject: [PATCH] chore(dpp): add method for decoding identifier with unknown string encoding (#2230) --- .../rs-platform-value/src/string_encoding.rs | 14 ++++++++++ .../rs-platform-value/src/types/identifier.rs | 26 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/rs-platform-value/src/string_encoding.rs b/packages/rs-platform-value/src/string_encoding.rs index c31d172839..bce2c69fbb 100644 --- a/packages/rs-platform-value/src/string_encoding.rs +++ b/packages/rs-platform-value/src/string_encoding.rs @@ -3,13 +3,27 @@ use base64; use base64::prelude::BASE64_STANDARD; use base64::Engine; use bs58; +use std::fmt; +#[derive(Debug, Copy, Clone)] pub enum Encoding { Base58, Base64, Hex, } +pub const ALL_ENCODINGS: [Encoding; 3] = [Encoding::Hex, Encoding::Base58, Encoding::Base64]; + +impl fmt::Display for Encoding { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Encoding::Base58 => write!(f, "Base58"), + Encoding::Base64 => write!(f, "Base64"), + Encoding::Hex => write!(f, "Hex"), + } + } +} + pub fn decode(encoded_value: &str, encoding: Encoding) -> Result, Error> { match encoding { Encoding::Base58 => Ok(bs58::decode(encoded_value) diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 07bdcbd425..19bfbf82b2 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -11,7 +11,8 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "json")] use serde_json::Value as JsonValue; -use crate::string_encoding::Encoding; +use crate::string_encoding::Encoding::Base58; +use crate::string_encoding::{Encoding, ALL_ENCODINGS}; use crate::types::encoding_string_to_encoding; use crate::{string_encoding, Error, Value}; @@ -170,6 +171,29 @@ impl Identifier { Identifier::from_bytes(&vec) } + pub fn from_string_try_encodings( + encoded_value: &str, + encodings: &[Encoding], + ) -> Result { + let mut tried = vec![]; + for encoding in encodings { + if let Ok(vec) = string_encoding::decode(encoded_value, *encoding) { + if vec.len() == 32 { + return Identifier::from_bytes(&vec); + } + } + tried.push(encoding.to_string()); + } + Err(Error::StringDecodingError(format!( + "Failed to decode string with encodings [{}]", + tried.join(", ") + ))) + } + + pub fn from_string_unknown_encoding(encoded_value: &str) -> Result { + Identifier::from_string_try_encodings(encoded_value, &ALL_ENCODINGS) + } + pub fn from_string_with_encoding_string( encoded_value: &str, encoding_string: Option<&str>,