Skip to content

Commit ed471fb

Browse files
committed
feat: validate token name localizations
1 parent ddf4e67 commit ed471fb

File tree

15 files changed

+156
-2
lines changed

15 files changed

+156
-2
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
pub mod v0;
2+
3+
use crate::data_contract::associated_token::token_configuration::accessors::v0::{
4+
TokenConfigurationV0Getters, TokenConfigurationV0Setters,
5+
};
6+
use crate::data_contract::associated_token::token_configuration_convention::accessors::v0::TokenConfigurationConventionV0Getters;
7+
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
8+
9+
impl TokenConfigurationConventionV0Getters for TokenConfigurationConvention {
10+
fn singular_form_by_language_code_or_default(&self, language_code: &str) -> &str {
11+
match self {
12+
TokenConfigurationConvention::V0(v0) => {
13+
v0.singular_form_by_language_code_or_default(language_code)
14+
}
15+
}
16+
}
17+
18+
fn plural_form_by_language_code_or_default(&self, language_code: &str) -> &str {
19+
match self {
20+
TokenConfigurationConvention::V0(v0) => {
21+
v0.plural_form_by_language_code_or_default(language_code)
22+
}
23+
}
24+
}
25+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// Accessor trait for getters of `TokenConfigurationConventionV0`
2+
pub trait TokenConfigurationConventionV0Getters {
3+
/// Returns the localized token name in singular form
4+
fn singular_form_by_language_code_or_default(&self, language_code: &str) -> &str;
5+
/// Returns the localized token name in plural form
6+
fn plural_form_by_language_code_or_default(&self, language_code: &str) -> &str;
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod validate_localizations;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
2+
use crate::validation::SimpleConsensusValidationResult;
3+
use crate::ProtocolError;
4+
use platform_version::version::PlatformVersion;
5+
6+
mod v0;
7+
8+
impl TokenConfigurationConvention {
9+
pub fn validate_localizations(
10+
&self,
11+
platform_version: &PlatformVersion,
12+
) -> Result<SimpleConsensusValidationResult, ProtocolError> {
13+
match platform_version
14+
.dpp
15+
.validation
16+
.data_contract
17+
.validate_localizations
18+
{
19+
0 => Ok(self.validate_localizations_v0()),
20+
version => Err(ProtocolError::UnknownVersionMismatch {
21+
method: "validate_localizations".to_string(),
22+
known_versions: vec![0],
23+
received: version,
24+
}),
25+
}
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use crate::consensus::basic::token::MissingDefaultLocalizationError;
2+
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
3+
use crate::validation::SimpleConsensusValidationResult;
4+
5+
impl TokenConfigurationConvention {
6+
#[inline(always)]
7+
pub(super) fn validate_localizations_v0(&self) -> SimpleConsensusValidationResult {
8+
let english_localization = match self {
9+
TokenConfigurationConvention::V0(v0) => v0.localizations.get("en"),
10+
};
11+
12+
// If there is no English localization, return an error
13+
if english_localization.is_none() {
14+
return SimpleConsensusValidationResult::new_with_error(
15+
MissingDefaultLocalizationError::new().into(),
16+
);
17+
}
18+
19+
// If we reach here with no errors, return an empty result
20+
SimpleConsensusValidationResult::new()
21+
}
22+
}

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use bincode::{Decode, Encode};
33
use derive_more::From;
44
use serde::{Deserialize, Serialize};
55

6+
mod accessors;
7+
mod methods;
68
pub mod v0;
79

810
#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, PartialOrd, From)]

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::data_contract::associated_token::token_configuration_convention::accessors::v0::TokenConfigurationConventionV0Getters;
12
use bincode::Encode;
23
use platform_serialization::de::Decode;
34
use serde::{Deserialize, Serialize};
@@ -22,11 +23,15 @@ impl fmt::Display for TokenConfigurationLocalizationsV0 {
2223
}
2324
}
2425

26+
pub const ENGLISH_ISO_639: &str = "en";
27+
2528
#[derive(
2629
Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, PartialOrd, Default,
2730
)]
2831
#[serde(rename_all = "camelCase")]
2932
pub struct TokenConfigurationConventionV0 {
33+
/// Localizations for the token name.
34+
/// The key must be a ISO 639 2-chars language code
3035
#[serde(default)]
3136
pub localizations: BTreeMap<String, TokenConfigurationLocalizationsV0>,
3237
#[serde(default = "default_decimals")]
@@ -54,3 +59,19 @@ impl fmt::Display for TokenConfigurationConventionV0 {
5459
)
5560
}
5661
}
62+
63+
impl TokenConfigurationConventionV0Getters for TokenConfigurationConventionV0 {
64+
fn singular_form_by_language_code_or_default(&self, language_code: &str) -> &str {
65+
self.localizations
66+
.get(language_code)
67+
.map(|localization| &localization.singular_form)
68+
.unwrap_or_else(|| &self.localizations[ENGLISH_ISO_639].singular_form)
69+
}
70+
71+
fn plural_form_by_language_code_or_default(&self, language_code: &str) -> &str {
72+
self.localizations
73+
.get(language_code)
74+
.map(|localization| &localization.plural_form)
75+
.unwrap_or_else(|| &self.localizations[ENGLISH_ISO_639].plural_form)
76+
}
77+
}

packages/rs-dpp/src/errors/consensus/basic/basic_error.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use crate::consensus::basic::overflow_error::OverflowError;
7474
use crate::consensus::basic::token::{
7575
ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError,
7676
DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenIdError,
77-
InvalidTokenPositionError, TokenTransferToOurselfError,
77+
InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError,
7878
};
7979
use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError;
8080
use crate::consensus::basic::value_error::ValueError;
@@ -469,6 +469,9 @@ pub enum BasicError {
469469
GroupNonUnilateralMemberPowerHasLessThanRequiredPowerError(
470470
GroupNonUnilateralMemberPowerHasLessThanRequiredPowerError,
471471
),
472+
473+
#[error(transparent)]
474+
MissingDefaultLocalizationError(MissingDefaultLocalizationError),
472475
}
473476

474477
impl From<BasicError> for ConsensusError {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use crate::consensus::basic::BasicError;
2+
use crate::consensus::ConsensusError;
3+
use crate::ProtocolError;
4+
use bincode::{Decode, Encode};
5+
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
6+
use thiserror::Error;
7+
#[derive(
8+
Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize,
9+
)]
10+
#[error("Missing english ('en') localization which is using by default")]
11+
#[platform_serialize(unversioned)]
12+
pub struct MissingDefaultLocalizationError {}
13+
14+
impl MissingDefaultLocalizationError {
15+
pub fn new() -> Self {
16+
Self {}
17+
}
18+
}
19+
20+
impl From<MissingDefaultLocalizationError> for ConsensusError {
21+
fn from(err: MissingDefaultLocalizationError) -> Self {
22+
Self::BasicError(BasicError::MissingDefaultLocalizationError(err))
23+
}
24+
}

packages/rs-dpp/src/errors/consensus/basic/token/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod destination_identity_for_token_minting_not_set_error;
44
mod invalid_action_id_error;
55
mod invalid_token_id_error;
66
mod invalid_token_position_error;
7+
mod missing_default_localization;
78
mod token_transfer_to_ourselves_error;
89

910
pub use choosing_token_mint_recipient_not_allowed_error::*;
@@ -12,4 +13,5 @@ pub use destination_identity_for_token_minting_not_set_error::*;
1213
pub use invalid_action_id_error::*;
1314
pub use invalid_token_id_error::*;
1415
pub use invalid_token_position_error::*;
16+
pub use missing_default_localization::*;
1517
pub use token_transfer_to_ourselves_error::*;

0 commit comments

Comments
 (0)