Skip to content

Commit

Permalink
DO NOT SUBMIT: ecma402 implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
filmil committed Jun 12, 2020
1 parent 5898178 commit 764bcb4
Show file tree
Hide file tree
Showing 15 changed files with 548 additions and 7 deletions.
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 {
/// 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;
}
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.2.3"

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.2.3", default-features = false }
rust_icu_sys = { path = "../rust_icu_sys", version = "0.2.3", default-features = false }
rust_icu_uloc = { path = "../rust_icu_uloc", version = "0.2.3", default-features = false }
rust_icu_ustring = { path = "../rust_icu_ustring", version = "0.2.3", default-features = false }
rust_icu_ulistformatter = { path = "../rust_icu_ulistformatter", version = "0.2.3", 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
18 changes: 18 additions & 0 deletions rust_icu_ecma402/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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.

// The list formatter uses features that are not available in ICU versions prior
// to 67.
pub mod listformat;

0 comments on commit 764bcb4

Please sign in to comment.