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

Ecma402 traits #125

Merged
merged 2 commits into from
Jun 13, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target
Cargo.lock
tags
target

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[workspace]
members = [
"ecma402_traits",
"rust_icu",
"rust_icu_common",
"rust_icu_ecma402",
"rust_icu_intl",
"rust_icu_sys",
"rust_icu_ucal",
Expand Down
15 changes: 10 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@ CARGO_FEATURE_VERSION :=
ICU_VERSION ?= $(shell icu-config --version)
ICU_MAJOR_VERSION ?= $(basename ${ICU_VERSION})
ICU_LIBDIR := $(shell icu-config --libdir)
PKG_CONFIG_PATH := "${HOME}/local/lib/pkgconfig:${PKG_CONFIG_PATH}"
LD_LIBRARY_PATH := "${ICU_LIBDIR}"
test:
@env PKG_CONFIG_PATH="${HOME}/local/lib/pkgconfig" \
LD_LIBRARY_PATH="${ICU_LIBDIR}" \
echo "ICU version detected: ${ICU_VERSION}" && \
echo "ICU major version detected: ${ICU_MAJOR_VERSION}"
cargo test && cargo doc
echo "ICU version detected: ${ICU_VERSION} ${ICU_LIBDIR}" \
&& echo "ICU major version detected: ${ICU_MAJOR_VERSION}" \
&& PKG_CONFIG_PATH=${PKG_CONFIG_PATH} \
LD_LIBRARY_PATH=${LD_LIBRARY_PATH} \
cargo test \
&& PKG_CONFIG_PATH=${PKG_CONFIG_PATH} \
LD_LIBRARY_PATH=${LD_LIBRARY_PATH} \
cargo doc
.PHONY: test

# Run a test inside a Docker container. The --volume mounts attach local dirs
Expand Down
19 changes: 19 additions & 0 deletions ecma402_traits/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
authors = ["Google Inc."]
default-features = false
edition = "2018"
keywords = ["ecma", "ecma402", "icu", "i18n", "l10n"]
license = "Apache-2.0"
name = "ecma402_traits"
readme = "README.md"
repository = "https://github.com/google/rust_icu"
version = "0.1.0"

description = """
Rust implementation of type traits to support ECMA 402 specification in Rust.

"""

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
1 change: 1 addition & 0 deletions ecma402_traits/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# WIP
38 changes: 38 additions & 0 deletions ecma402_traits/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;

/// This trait contains the common features of the Locale object that must be shared among
/// all the implementations. Every implementor of `listformat` should provide their
/// own version of [Locale], and should ensure that it implements [Locale]. as
/// specified here.
///
/// For the time being we agreed that a [Locale] *must* be convertible into its string
/// form, using `Display`.
pub trait Locale: fmt::Display {}

/// A Rust implementation of ECMA 402 ListFormat API.
///
/// The [listformat] mod contains all the needed implementation bits for `Intl.ListFormat`.
///
pub mod listformat;

#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
121 changes: 121 additions & 0 deletions ecma402_traits/src/listformat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Contains the API configuration as prescribed by ECMA 402.
///
/// The meaning of the options is the same as in the similarly named
/// options in the JS version.
///
/// See [Options] for the contents of the options. See the [Format::try_new]
/// for the use of the options.
pub mod options {
/// Chooses the list formatting approach.
#[derive(Eq, PartialEq, Debug, Clone)]
pub enum Style {
Long,
Short,
Narrow,
}
/// Chooses between "this, that and other", and "this, that or other".
#[derive(Eq, PartialEq, Debug, Clone)]
pub enum Type {
/// "This, that and other".
Conjunction,
/// "This, that or other".
Disjunction,
}
}

/// The options set by the user at construction time. See discussion at the top level
/// about the name choice. Provides as a "bag of options" since we don't expect any
/// implementations to be attached to this struct.
///
/// The default values of all the options are prescribed in by the [TC39 report][tc39lf].
///
/// [tc39lf]: https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Options {
/// Selects a [options::Style] for the formatted list. If unset, defaults
/// to [options::Style::Long].
pub style: options::Style,
/// Selects a [options::Type] for the formatted list. If unset, defaults to
/// [options::Type::Conjunction].
pub in_type: options::Type,
}

/// Allows the use of `listformat::Format::try_new(..., Default::default())`.
impl Default for Options {
/// Gets the default values of [Options] if omitted at setup. The
/// default values are prescribed in by the [TC39 report][tc39lf].
///
/// [tc39lf]: https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat
fn default() -> Self {
Options {
style: options::Style::Long,
in_type: options::Type::Conjunction,
}
}
}

use std::fmt;

/// The package workhorse: formats supplied pieces of text into an ergonomically formatted
/// list.
///
/// While ECMA 402 originally has functions under `Intl`, we probably want to
/// obtain a separate factory from each implementor.
///
/// Purposely omitted:
///
/// - `supported_locales_of`.
pub trait Format {
filmil marked this conversation as resolved.
Show resolved Hide resolved
/// The type of error reported, if any.
type Error: std::error::Error;

/// Creates a new [Format].
///
/// Creation may fail, for example, if the locale-specific data is not loaded, or if
/// the supplied options are inconsistent.
fn try_new<L>(l: L, opts: Options) -> Result<Self, Self::Error>
where
L: crate::Locale,
Self: Sized;

/// Formats `list` into the supplied standard `writer` [fmt::Write].
///
/// The original [ECMA 402 function][ecma402fmt] returns a string. This is likely the only
/// reasonably generic option in JavaScript so it is adequate. In Rust, however, it is
/// possible to pass in a standard formatting strategy (through `writer`).
///
/// [ecma402fmt]:
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/format
///
/// This makes it unnecessary for [Format] to implement its own, and can
/// completely avoid constructing any intermediary representation. This, in turn,
/// allows the user to provide a purpose built formatter, or an "exotic" one if needed.
///
/// A purpose built formatter could be one that formats into a fixed-size buffer; or
/// another that knows how to format strings into a DOM. If ECMA 402 compatibility is
/// needed, the user can force formatting into a string by passing the appropriate
/// formatter.
///
/// > Note:
/// > - Should there be a convenience method that prints to string specifically?
/// > - Do we need `format_into_parts`?
fn format<I, L, W>(self, list: L, writer: &mut W) -> fmt::Result
where
I: fmt::Display,
L: IntoIterator<Item = I>,
W: fmt::Write;
}
File renamed without changes.
8 changes: 8 additions & 0 deletions rust_icu_common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ impl From<std::string::FromUtf8Error> for Error {
}
}

impl Into<std::fmt::Error> for Error {
fn into(self) -> std::fmt::Error {
// It is not possible to transfer any info into std::fmt::Error, so we log instead.
eprintln!("error while formatting: {:?}", &self);
std::fmt::Error{}
}
}

/// Generates a method to wrap ICU4C `uloc` methods that require a resizable output string buffer.
///
/// The various `uloc` methods of this type have inconsistent signature patterns, with some putting
Expand Down
80 changes: 80 additions & 0 deletions rust_icu_ecma402/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[package]
authors = ["Google Inc."]
default-features = false
edition = "2018"
keywords = ["icu", "unicode", "i18n", "l10n"]
license = "Apache-2.0"
name = "rust_icu_ecma402"
readme = "README.md"
repository = "https://github.com/google/rust_icu"
version = "0.3.0"

description = """
ECMA 402 standard implementation in Rust.
"""
[dependencies]
anyhow = "1.0.25"
ecma402_traits = { path = "../ecma402_traits", version = "0.1.0" }
log = "0.4.6"
paste = "0.1.5"
rust_icu_common = { path = "../rust_icu_common", version = "0.3.0", default-features = false }
rust_icu_sys = { path = "../rust_icu_sys", version = "0.3.0", default-features = false }
rust_icu_uloc = { path = "../rust_icu_uloc", version = "0.3.0", default-features = false }
rust_icu_ustring = { path = "../rust_icu_ustring", version = "0.3.0", default-features = false }
rust_icu_ulistformatter = { path = "../rust_icu_ulistformatter", version = "0.3.0", default-features = false }

[dev-dependencies]
anyhow = "1.0.25"

# See the feature description in ../rust_icu_sys/Cargo.toml for details.
[features]
default = ["use-bindgen", "renaming", "icu_config"]

use-bindgen = [
"rust_icu_common/use-bindgen",
"rust_icu_sys/use-bindgen",
"rust_icu_ulistformatter/use-bindgen",
"rust_icu_uloc/use-bindgen",
"rust_icu_ustring/use-bindgen",
]
renaming = [
"rust_icu_common/renaming",
"rust_icu_sys/renaming",
"rust_icu_ulistformatter/renaming",
"rust_icu_uloc/renaming",
"rust_icu_ustring/renaming",
]
icu_config = [
"rust_icu_common/icu_config",
"rust_icu_sys/icu_config",
"rust_icu_ulistformatter/icu_config",
"rust_icu_uloc/icu_config",
"rust_icu_ustring/icu_config",
]
icu_version_in_env = [
"rust_icu_common/icu_version_in_env",
"rust_icu_sys/icu_version_in_env",
"rust_icu_ulistformatter/icu_version_in_env",
"rust_icu_uloc/icu_version_in_env",
"rust_icu_ustring/icu_version_in_env",
]
icu_version_64_plus = [
"rust_icu_common/icu_version_64_plus",
"rust_icu_sys/icu_version_64_plus",
"rust_icu_ustring/icu_version_64_plus",
"rust_icu_uloc/icu_version_64_plus",
"rust_icu_ulistformatter/icu_version_64_plus",
]
icu_version_67_plus = [
"rust_icu_common/icu_version_67_plus",
"rust_icu_sys/icu_version_67_plus",
"rust_icu_ustring/icu_version_67_plus",
"rust_icu_uloc/icu_version_67_plus",
"rust_icu_ulistformatter/icu_version_67_plus",
]

[badges]
maintenance = { status = "actively-developed" }
is-it-maintained-issue-resolution = { repository = "google/rust_icu" }
is-it-maintained-open-issues = { repository = "google/rust_icu" }
travis-ci = { repository = "google/rust_icu", branch = "master" }
1 change: 1 addition & 0 deletions rust_icu_ecma402/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# WIP
17 changes: 17 additions & 0 deletions rust_icu_ecma402/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Implements ECMA-402 `Intl.ListFormat`.
pub mod listformat;