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

System locale #5081

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

System locale #5081

wants to merge 22 commits into from

Conversation

ashu26jha
Copy link
Contributor

@ashu26jha ashu26jha commented Jun 19, 2024

Mentors: @robertbastian @zbraniecki

Total tasks:

  • Retrieval of system locale for MacOS, Windows, Linux
  • Calendar preferences
  • Time Zone
  • Convert String into icu4x components

Optional:

  • Number preferences
  • Currency preferences
  • Temperature
  • First Day of week
if !locale_ptr.is_null() {
let c_str = CStr::from_ptr(locale_ptr);
if let Ok(str_slice) = c_str.to_str() {
return vec![(str_slice.to_string(), String::from("Gregorian"))];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gregorian is default calendar for linux (doesn't change even changing the locale, won't work unless install extensions). Ubuntu uses GNOME calendar. Here is something in their repo: https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/998

Copy link
Member

Choose a reason for hiding this comment

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

please add this as a code comment

Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done

Comment on lines 10 to 30
pub fn get_locale() -> Vec<String> {
#[cfg(target_os = "linux")]
return linux::get_locale();

#[cfg(target_os = "macos")]
return apple::get_locale();

#[cfg(target_os = "windows")]
return windows::get_locale();
}

pub fn get_system_calendar() -> Vec<(String, String)> {
#[cfg(target_os = "linux")]
return linux::get_system_calendar();

#[cfg(target_os = "macos")]
return apple::get_system_calendar();

#[cfg(target_os = "windows")]
return windows::get_system_calendar();
}
Copy link
Member

Choose a reason for hiding this comment

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

reexport the methods instead of wrapping them:

Suggested change
pub fn get_locale() -> Vec<String> {
#[cfg(target_os = "linux")]
return linux::get_locale();
#[cfg(target_os = "macos")]
return apple::get_locale();
#[cfg(target_os = "windows")]
return windows::get_locale();
}
pub fn get_system_calendar() -> Vec<(String, String)> {
#[cfg(target_os = "linux")]
return linux::get_system_calendar();
#[cfg(target_os = "macos")]
return apple::get_system_calendar();
#[cfg(target_os = "windows")]
return windows::get_system_calendar();
}
#[cfg(target_os = "linux")]
pub use linux::*;
#[cfg(target_os = "macos")]
pub use apple::*;
#[cfg(target_os = "windows")]
pub use windows::*;
Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done?

utils/system_locale/src/linux.rs Outdated Show resolved Hide resolved
let mut locale_map = HashMap::new();

if let Ok(str_slice) = c_str.to_str() {
if str_slice.contains(';') {
Copy link
Member

Choose a reason for hiding this comment

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

contains requires a full scan of the string, try to write the algorithm with just split.

ptr::null,
};

pub unsafe fn fetch_locale_settings() -> HashMap<i32, String> {
Copy link
Member

Choose a reason for hiding this comment

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

this method should be either be safe, or private. If safe, any unsafeness should be encapsulated inside. If unsafe, it should have a comment stating the requirements for it to be safe.

Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest abstracting the LC_* to an enum and have this return HashMap<THIS_ENUM, Locale>

Copy link
Member

Choose a reason for hiding this comment

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

agreed

utils/system_locale/src/linux.rs Outdated Show resolved Hide resolved
return windows::get_locale();
}

pub fn get_system_calendar() -> Vec<(String, String)> {
Copy link
Member

Choose a reason for hiding this comment

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

also, plural?

Copy link
Member

Choose a reason for hiding this comment

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

get_env_calendars ?

Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done for windows

Comment on lines 1 to 2
#[cfg(target_os = "linux")]
mod linux_locale {
Copy link
Member

Choose a reason for hiding this comment

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

This file (= module) is already gated on linux, you don't need a nested module.

Suggested change
#[cfg(target_os = "linux")]
mod linux_locale {
Copy link
Member

Choose a reason for hiding this comment

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

still nested

utils/system_locale/src/linux.rs Outdated Show resolved Hide resolved
utils/system_locale/src/apple.rs Outdated Show resolved Hide resolved
utils/system_locale/src/windows.rs Outdated Show resolved Hide resolved
Cargo.toml Outdated
@@ -66,6 +66,7 @@ members = [
"utils/litemap",
"utils/pattern",
"utils/resb",
"utils/system_locale",
Copy link
Member

Choose a reason for hiding this comment

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

This name suggests that the crate only retrieves "system" "locale". My understanding is that your crate aims to retrieve environment information from the runtime. I'd use a term like "environment", "preferences" etc.

My concern about the "system" is that it indicates that what you get is "OS Locale" - but you may not. Increasingly OSes sandbox applications, so OS may be in English, but the application may only see that the language of its own environment is French.
My concern about "locale" is that it indicates that all you get is a Unicode Locale - while what you actually get are things beyond that. For example, short date pattern is not part of a Locale but should be retrievable by this crate.

Maybe "utils/env_preferences"?

return windows::get_locale();
}

pub fn get_system_calendar() -> Vec<(String, String)> {
Copy link
Member

Choose a reason for hiding this comment

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

get_env_calendars ?

ptr::null,
};

pub unsafe fn fetch_locale_settings() -> HashMap<i32, String> {
Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest abstracting the LC_* to an enum and have this return HashMap<THIS_ENUM, Locale>

@ashu26jha ashu26jha marked this pull request as ready for review July 7, 2024 06:18
@ashu26jha ashu26jha requested a review from a team as a code owner July 7, 2024 06:18
Copy link
Member

@robertbastian robertbastian left a comment

Choose a reason for hiding this comment

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

There are still a lot of unaddressed comments from my first review

// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

// The test is just here to silence the compiler warning, meaningful test will be added later
Copy link
Member

Choose a reason for hiding this comment

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

this should not be required, what's the compiler warning?

Copy link
Member

Choose a reason for hiding this comment

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

issue: remove

};
use std::ffi::CStr;

pub fn get_locales_mac() -> Vec<String> {
Copy link
Member

Choose a reason for hiding this comment

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

mac? apple? macos? You shouldn't need suffixes, as all these methods are in the apple namespace already.

locale_map
}

pub fn get_locales_linux() -> Vec<String> {
Copy link
Member

Choose a reason for hiding this comment

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

suffixes also not needed

if !locale_ptr.is_null() {
let c_str = CStr::from_ptr(locale_ptr);
if let Ok(str_slice) = c_str.to_str() {
return vec![(str_slice.to_string(), String::from("Gregorian"))];
Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done

Cow::Owned(str_slice.to_string()),
Cow::Borrowed("Gregorian"),
))
.into_iter(),
Copy link
Member

Choose a reason for hiding this comment

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

If you add

Suggested change
.into_iter(),
.into_iter().chain(None),

then both paths return the same type, and you don't need to wrap things in boxes and use dyn.

Comment on lines 52 to 61
pub fn get_locale() -> Vec<String> {
let mut unique_locales = HashSet::new();
unsafe {
let locale_map = fetch_locale_settings();
for value in locale_map.values() {
unique_locales.insert(value.clone());
}
}
unique_locales.into_iter().collect()
}
Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done, now it's just fetch_locale_settings().into_values()

#[cfg(target_os = "windows")]
mod windows;

pub fn get_locale() -> Vec<String> {
Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done for windows

return windows::get_locale();
}

pub fn get_system_calendar() -> Vec<(String, String)> {
Copy link
Member

Choose a reason for hiding this comment

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

still needs to be done for windows

Comment on lines 1 to 2
#[cfg(target_os = "linux")]
mod linux_locale {
Copy link
Member

Choose a reason for hiding this comment

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

still nested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants