Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

twine extension #7

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

twine extension #7

wants to merge 5 commits into from

Conversation

rzerres
Copy link

@rzerres rzerres commented Mar 22, 2021

Contents

When i was searching of an alternate i18n crate i found twine-rust.
I wanted to give it a try, but had problems to integrate it in my app. So i started to dig in.
I haven't adapted the documentation, but wanted to share my little improvements.

lib.rs: enhancements

  • impl Default for Lang
  • newline corrections
  • correct linter hint (lifetime definition)

twine-demo: add demo app

If you are working in a project, where code is organized in subtrees, i played with the best spots to include the macro. This little test app rebuilds a small structure that is supporting a library and binary part. Haven't got a clue how to preset the Language OS-agnostic, since Windows isn't using the default LANG approach. If you have a clue, this probably will improve the acceptence of the audiance.

  • use workspace
  • adopt test-crate

Greetings
Ralf

Copy link
Member

@cecton cecton left a comment

Choose a reason for hiding this comment

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

Hello!! 👋 Thanks a lot for joining the party!

So first let me answer your proposed improvements:

  • impl Default for Lang

Ok that sounds like a good idea but what should be the default language?

For what I read I think your intention is to use the language from the execution environment. Unfortunately I don't think this is possible as there is not a 1:1 mapping between the OS's specific language to the languages defined by Twine.

My current recommendation is that the user defines their default on their own. For example, this is perfectly legal to do:

// get the macro (t!) accessing the internationalization strings & the Lang enum!
include!(concat!(env!("OUT_DIR"), "/i18n.rs"));

// Please note that you *CAN* implement Default on Lang because Lang is NOT a foreign type.
impl Default for Lang {
    fn default() -> Self {
        Lang::En("")
    }
}

But maybe the users don't realize this is possible so I'm not against one of these solutions:

  • adding an example in examples showing it
  • adding an optional parameter "default_lang" to the functions that generate the code to allow optionally defining a default language
  • find a crate on crates.io that handles the "default" language well and provide some API to allow the user to do the mapping (this would need to go behind a feature flag because of the complexity and weight)
  • assuming the first language to appear is the default one, like this:
[err_lang_not_found]
	de = Konnte Sprachkode nicht auslesen
	en = Can not read the language code

☝️ de appears first so de is the default one.

  • newline corrections

Great, thanks!

  • correct linter hint (lifetime definition)

Great! ...I didn't get these linter hint issue... How did you get them? clippy? rustc? Do you have a screenshot?

Second: PR review itself.

I think your intention was to make an example crate and not a test crate. The difference is that the example crate is targeted to teach the user how to use and integrate the library in their project. The test crate focuses only on making sure the library works as intended.

src/lib.rs Outdated Show resolved Hide resolved
twine-test/Cargo.toml Outdated Show resolved Hide resolved
twine-test/src/main.rs Outdated Show resolved Hide resolved
@rzerres
Copy link
Author

rzerres commented Mar 29, 2021

My current recommendation is that the user defines their default on their own. For example, this is perfectly legal to do:

Fine, i wasn't aware of this. Good to know. And yes, this should be mentioned in the README.md

@rzerres
Copy link
Author

rzerres commented Mar 29, 2021

* assuming the first language to appear is the default one, like this:

That would be my opt in.
If this isn't appropriate, user can impl Default for Lang {} as suggested.

Copy link
Member

@cecton cecton left a comment

Choose a reason for hiding this comment

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

* assuming the first language to appear is the default one, like this:

That would be my opt in.
If this isn't appropriate, user can impl Default for Lang {} as suggested.

The problem with that is that if twine does impl Default already for you, the user won't be able to do it.

I think it's best you remove the Default implementation and add a note in the crate's documentation instead so the user has maximum flexibility.

So here is a list of changes that sounds reasonable to me:

  • Update the crate's documentation. The README is generated automatically using cargo-readme
  • The example you provided need to be moved again to the directory examples/. The complete path is examples/twine-demo/
  • Add a Default impl for Lang in the example to illustrate how to do that
  • Simplify the example

//println!{"lang: {}", &lang};

// include localization strings
let lang = Lang::De("de");
Copy link
Member

Choose a reason for hiding this comment

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

I find it weird that you are adding a Default impl but you don't seem to use it anywhere.

May I ask, do you have an actual use case where you need Lang::default()? Can you show me or explain

Comment on lines 27 to 31
//let mut lang = env::var("LANG").unwrap_or_else(|_| "en".to_string());
//let lang_culture = lang.substring(3,4).to_string(); // "de_DE.UTF-8" -> "DE"
//let lang_family = lang.substring(0,2).to_string(); // "de_DE.UTF-8" -> "de"
//lang = format!{"Lang::{}(\"{}\")", &lang_culture, &lang_family};
//println!{"lang: {}", &lang};
Copy link
Member

Choose a reason for hiding this comment

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

Remove all commented code

Comment on lines 11 to 42
pub fn import(p: &mut String, lang: &Lang) -> Result<Duration, Box<dyn Error>> {
use std::path::Path;

let mut res = t!(import_started => lang);
let mut state = t!(state_started => lang);

let time_start = SystemTime::now();
trace!(target: "import", process = ?res, state = ?state,
date_start = ?time_start);

let path = Path::new(p);
assert_eq!(path.is_file(), true);
trace!(target: "import", path = ?path);

let mut child = Command::new("sleep").arg("5").spawn().unwrap();
let _result = child.wait().unwrap();

let mut time_end = SystemTime::now();
let duration = time_end
.duration_since(time_start)
.expect("Clock may have gone backwards");
trace!(target: "import", duration = ?duration);

state = t!(state_finished => lang);
res = t!(import_finished => lang);

time_end = SystemTime::now();
trace!(target: "import", process = ?res, state = ?state,
date_stop = ?time_end);

Ok(duration)
}
Copy link
Member

Choose a reason for hiding this comment

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

Please do not use p. The languages are supposed to be loaded at compile time and it is very confusing that you are now checking something with the .rs file that has been generated.

trace!(target: "twine-demo", state = ?state,
res = ? res, time = ?time_start);

let mut import_path = concat!(env!("OUT_DIR"), "/i18n.rs").to_string();
Copy link
Member

Choose a reason for hiding this comment

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

Don't do that

Copy link
Member

Choose a reason for hiding this comment

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

I mean this file is not meant to be read at runtime. It makes no sense to do this.

Copy link
Author

Choose a reason for hiding this comment

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

You are right. Will clean it up and rebase the twine-demo code to be more intutive.

* impl Default for Lang
* newline corrections
* correct linter hint (lifetime definition)

Signed-off-by: Ralf Zerres <[email protected]>
* use workspace
* adopt test-crate

Signed-off-by: Ralf Zerres <[email protected]>
Comment on lines +354 to +358
sorted_languages.sort_unstable();

let (default_lang, default_region) = sorted_languages[0];
Copy link
Member

Choose a reason for hiding this comment

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

You're still taking the first language in alphabetical order. This is not good.

Copy link
Author

Choose a reason for hiding this comment

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

Yeh,
didn't go into it. Actually i might just get rid of a default branch. User must choose explicitely for the language to choose.
I might implement something in the twine-demo code ....

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good to me

@rzerres rzerres force-pushed the wip_twine branch 3 times, most recently from 4c63c8f to e3901bd Compare June 12, 2021 23:35
* choose first member of sorted languages as proposte default lang
* rename `twine-test` to `twine-demo`
* since `twine-demo` is a crate, it will be handled as a workspace
  examples can't be build using a Cargo.toml
* update Cargo.toml to meet the corrections
* update README.md

Signed-off-by: Ralf Zerres <[email protected]>
* if compile call activates macro "missing_docs"
  provide suitable documentation strings

Signed-off-by: Ralf Zerres <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants