Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions dsc/tests/dsc_i18n.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,6 @@ BeforeDiscovery {
if (Test-Path -Path $tomlFile) {
$this.LoadFile((Get-Item -Path $tomlFile))
}
$yamlFiles = Get-ChildItem -Path $localesFolder | Where-Object Extension -match 'ya?ml'
foreach ($yamlFile in $yamlFiles) {
$this.LoadFile($yamlFile)
}

$this.CheckTranslations($projectFolder)
}
Expand Down
41 changes: 39 additions & 2 deletions lib/dsc-lib-jsonschema-macros/src/derive/dsc_repo_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ struct DscRepoSchemaReceiver {
/// other schemas may not be.
#[darling(default)]
pub should_bundle: bool,
/// Defines the root dotpath for the JSON Schema keyword value translations used by `rust_i18n`
/// crate. Must be a literal string like `"schemas.definitions.tag"`.
#[darling(default)]
pub i18n_root_key: Option<String>,
/// Defines the field for the struct that is used as the `$schema` property. Typically only
/// defined for root schemas.
#[darling(default)]
Expand Down Expand Up @@ -62,6 +66,12 @@ pub(crate) fn dsc_repo_schema_impl(input: TokenStream) -> TokenStream {
}
};

let i18n_root_key = args.i18n_root_key.unwrap_or(format!(
"schemas.{}.{}",
args.folder_path.replace('/', "."),
args.base_name
));

Comment thread
michaeltlombardi marked this conversation as resolved.
let mut output = quote!();

if let Some(schema_field) = args.schema_field {
Expand All @@ -70,14 +80,16 @@ pub(crate) fn dsc_repo_schema_impl(input: TokenStream) -> TokenStream {
args.base_name,
args.folder_path,
args.should_bundle,
i18n_root_key,
schema_field
));
} else {
output.extend(generate_without_schema_field(
ident,
args.base_name,
args.folder_path,
args.should_bundle
args.should_bundle,
i18n_root_key
));
}

Expand All @@ -91,14 +103,19 @@ fn generate_without_schema_field(
ident: Ident,
base_name: String,
folder_path: String,
should_bundle: bool
should_bundle: bool,
i18n_root_key: String,
) -> proc_macro2::TokenStream {
let translation_fn = generate_schema_i18n_fn();
quote!(
#[automatically_derived]
impl DscRepoSchema for #ident {
const SCHEMA_FILE_BASE_NAME: &'static str = #base_name;
const SCHEMA_FOLDER_PATH: &'static str = #folder_path;
const SCHEMA_SHOULD_BUNDLE: bool = #should_bundle;
const SCHEMA_I18N_ROOT_KEY: &'static str = #i18n_root_key;

#translation_fn

fn schema_property_metadata() -> schemars::Schema {
schemars::json_schema!({})
Expand All @@ -118,16 +135,21 @@ fn generate_with_schema_field(
base_name: String,
folder_path: String,
should_bundle: bool,
i18n_root_key: String,
schema_field: DscRepoSchemaField
) -> proc_macro2::TokenStream {
let schema_property_metadata = generate_schema_property_metadata_fn(&schema_field);
let translation_fn = generate_schema_i18n_fn();
let field = schema_field.name;
quote!(
#[automatically_derived]
impl DscRepoSchema for #ident {
const SCHEMA_FILE_BASE_NAME: &'static str = #base_name;
const SCHEMA_FOLDER_PATH: &'static str = #folder_path;
const SCHEMA_SHOULD_BUNDLE: bool = #should_bundle;
const SCHEMA_I18N_ROOT_KEY: &'static str = #i18n_root_key;

#translation_fn

#schema_property_metadata

Expand Down Expand Up @@ -169,3 +191,18 @@ fn generate_schema_property_metadata_fn(schema_field: &DscRepoSchemaField) -> pr
}
}
}

/// Generates a crate-local implementation for the `schema_i18n()` trait function. This is
/// required to ensure that the translations use the correct locale definitions.
fn generate_schema_i18n_fn() -> proc_macro2::TokenStream {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this increase the binary size in any impactful way? If so, perhaps we can do the check only on debug builds?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so:

  1. The size of the implementation for this is very small - the method itself is very small and is primarily calling existing code.
  2. The implementation here mirrors the expansion of the t!() macro except that we error on a missing translation string instead of emitting the failed lookup as the translation string, e.g t!("unedefined.translation") would emit "undefined.translation".
  3. The majority of the size comes from the existing i18n macros, particularly the translation lookup map tat it generates.
  4. I'm not sure how we can effectively gate this on build configuration without either starting the work to separate the dsc schema command into its own crate or stripping the schema documentation keywords. We could possibly use cfg_attr but that will get very messy very quickly for annotating structs.

quote! {
fn schema_i18n(suffix: &str) -> Result<String, dsc_lib_jsonschema::dsc_repo::DscRepoSchemaMissingTranslation> {
let i18n_key = format!("{}.{}", Self::SCHEMA_I18N_ROOT_KEY, suffix);
if let Some(translated) = crate::_rust_i18n_try_translate(&rust_i18n::locale(), &i18n_key) {
Ok(translated.into())
} else {
Err(dsc_lib_jsonschema::dsc_repo::DscRepoSchemaMissingTranslation { i18n_key })
}
}
}
}
Loading
Loading