fluent-langneg-0.13.0/.cargo_vcs_info.json0000644000000001121365462631000141210ustar00{ "git": { "sha1": "29007f8d453b931b79544566b1037865bfa7fb12" } } fluent-langneg-0.13.0/Cargo.lock0000644000000775001365462631000121130ustar00# This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bstr" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bumpalo" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cast" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion-plot" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-deque" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-queue" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "csv" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bstr 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "csv-core" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fluent-langneg" version = "0.13.0" dependencies = [ "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "unic-langid 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unic-locale 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hermit-abi" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itertools" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "js-sys" version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "log" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memoffset" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num_cpus" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "oorandom" version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "plotters" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro-hack" version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "regex-syntax 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-automata" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ryu" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tinystr" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "tinytemplate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-langid" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unic-langid-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unic-langid-macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-langid-impl" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "tinystr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-langid-macros" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "tinystr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "unic-langid-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unic-langid-macros-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-langid-macros-impl" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "unic-langid-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-locale" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unic-langid-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unic-locale-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unic-locale-macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-locale-impl" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "tinystr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "unic-langid-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-locale-macros" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "tinystr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "unic-locale-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unic-locale-macros-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unic-locale-macros-impl" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "unic-locale-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen" version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro-support 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "web-sys" version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bstr 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" "checksum bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1" "checksum criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545" "checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" "checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" "checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" "checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" "checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" "checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" "checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" "checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" "checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" "checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" "checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" "checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" "checksum regex-syntax 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" "checksum syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum tinystr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac79c4b51eda1b090b1edebfb667821bbb51f713855164dc7cec2cb8ac2ba3" "checksum tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a" "checksum unic-langid 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5" "checksum unic-langid-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d" "checksum unic-langid-macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18f980d6d87e8805f2836d64b4138cc95aa7986fa63b1f51f67d5fbff64dd6e5" "checksum unic-langid-macros-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29396ffd97e27574c3e01368b1a64267d3064969e4848e2e130ff668be9daa9f" "checksum unic-locale 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f7e9b9d143ba4062fae4e3be1c6a4d31ddc5bc03b7984926ac19d7f303101cb7" "checksum unic-locale-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f29943aedbc131c17267cead15545446e0fd97f7489cc064c7114f0cd6cf7b1f" "checksum unic-locale-macros 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b97b592a3a0768bcb486578d66116379861ad8fd6375fa0360f29320d780cd1e" "checksum unic-locale-macros-impl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cbbc18c45eb084013209367d522ed4f360f0312e17f5f3e5ebbc9d95671a59" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d" "checksum wasm-bindgen-backend 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8" "checksum wasm-bindgen-macro 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205" "checksum wasm-bindgen-macro-support 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d" "checksum wasm-bindgen-shared 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8" "checksum web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)" = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" fluent-langneg-0.13.0/Cargo.toml0000644000000031611365462631000121260ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "fluent-langneg" version = "0.13.0" authors = ["Zibi Braniecki "] include = ["src/**/*", "benches/*.rs", "Cargo.toml", "README.md"] description = "A library for language and locale negotiation.\n" homepage = "http://projectfluent.org/" readme = "README.md" categories = ["internationalization", "localization"] license = "Apache-2.0" repository = "https://github.com/projectfluent/fluent-langneg-rs" [[bench]] name = "negotiate" harness = false [dependencies.unic-langid] version = "0.9" [dev-dependencies.criterion] version = "0.3" [dev-dependencies.serde] version = "1.0" features = ["derive"] [dev-dependencies.serde_json] version = "1.0" [dev-dependencies.unic-langid] version = "0.9" features = ["macros"] [dev-dependencies.unic-locale] version = "0.9" features = ["macros"] [features] cldr = ["unic-langid/likelysubtags"] default = [] [badges.coveralls] branch = "master" repository = "projectfluent/fluent-langneg-rs" service = "github" [badges.maintenance] status = "actively-developed" [badges.travis-ci] repository = "projectfluent/fluent-langneg-rs" fluent-langneg-0.13.0/Cargo.toml.orig010064400017500001731000000020371365462623400156250ustar0000000000000000[package] name = "fluent-langneg" description = """ A library for language and locale negotiation. """ version = "0.13.0" authors = ["Zibi Braniecki "] homepage = "http://projectfluent.org/" license = "Apache-2.0" repository = "https://github.com/projectfluent/fluent-langneg-rs" readme = "README.md" categories = ["internationalization", "localization"] edition = "2018" include = [ "src/**/*", "benches/*.rs", "Cargo.toml", "README.md" ] [badges] travis-ci = { repository = "projectfluent/fluent-langneg-rs" } coveralls = { repository = "projectfluent/fluent-langneg-rs", branch = "master", service = "github" } maintenance = { status = "actively-developed" } [dependencies] unic-langid = "0.9" [dev-dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" unic-langid = { version = "0.9", features = ["macros"] } unic-locale = { version = "0.9", features = ["macros"] } criterion = "0.3" [[bench]] name = "negotiate" harness = false [features] default = [] cldr = ["unic-langid/likelysubtags"] fluent-langneg-0.13.0/README.md010064400017500001731000000104271360773304100142100ustar0000000000000000# Fluent LangNeg **Fluent LangNeg is a library for language and locale identifier negotiation.** [![crates.io](http://meritbadge.herokuapp.com/fluent-langneg)](https://crates.io/crates/fluent-langneg) [![Build Status](https://travis-ci.org/projectfluent/fluent-langneg-rs.svg?branch=master)](https://travis-ci.org/projectfluent/fluent-langneg-rs) [![Coverage Status](https://coveralls.io/repos/github/projectfluent/fluent-langneg-rs/badge.svg?branch=master)](https://coveralls.io/github/projectfluent/fluent-langneg-rs?branch=master) Introduction ------------ This is a Rust implementation of fluent-langneg library which is a part of Project Fluent. The library uses [unic-langid](https://github.com/zbraniecki/unic-locale) and [unic-locale](https://github.com/zbraniecki/unic-locale) to retrieve and operate on Unicode Language and Locale Identifiers. The library provides algorithm for negotiating between lists of locales. Usage ----- ```rust use fluent_langneg::negotiate_languages; use fluent_langneg::NegotiationStrategy; use fluent_langneg::convert_vec_str_to_langids_lossy; use unic_langid::LanguageIdentifier // Since langid parsing from string is fallible, we'll use a helper // function which strips any langids that failed to parse. let requested = convert_vec_str_to_langids_lossy(&["de-DE", "fr-FR", "en-US"]); let available = convert_vec_str_to_langids_lossy(&["it", "fr", "de-AT", "fr-CA", "en-US"]); let default: LanguageIdentifier = "en-US".parse().expect("Parsing langid failed."); let supported = negotiate_languages( &requested, &available, Some(&default), NegotiationStrategy::Filtering ); let expected = convert_vec_str_to_langids_lossy(&["de-AT", "fr", "fr-CA", "en-US"]); assert_eq!(supported, expected.iter().map(|t| t.as_ref()).collect::>()); ``` See [docs.rs][] for more examples. [docs.rs]: https://docs.rs/fluent-langneg/ Status ------ The implementation is complete according to fluent-langneg corpus of tests, which means that it parses, serializes and negotiates as expected. The negotiation methods can operate on lists of `LanguageIdentifier` or `Locale`. The remaining work is on the path to 1.0 is to gain in-field experience of using it, add more tests and ensure that bad input is correctly handled. Compatibility ------------- The API is based on [UTS 35][] definition of [Unicode Locale Identifier][] and is aiming to parse and serialize all locale identifiers according to that definition. *Note*: Unicode Locale Identifier is similar, but different, from what [BCP47][] specifies under the name Language Tag. For most locale management and negotiation needs, the Unicode Locale Identifier used in this crate is likely a better choice, but in some case, like HTTP Accepted Headers, you may need the complete BCP47 Language Tag implementation which this crate does not provide. Language negotiation algorithms are custom Project Fluent solutions, based on [RFC4647][]. The language negotiation strategies aim to replicate the best-effort matches with the most limited amount of data. The algorithm returns reasonable results without any database, but the results can be improved with either limited or full [CLDR likely-subtags][] database. The result is a balance chosen for Project Fluent and may differ from other implementations of language negotiation algorithms which may choose different tradeoffs. [BCP47]: https://tools.ietf.org/html/bcp47 [RFC6067]: https://www.ietf.org/rfc/rfc6067.txt [UTS 35]: http://www.unicode.org/reports/tr35/#Locale_Extension_Key_and_Type_Data [RFC4647]: https://tools.ietf.org/html/rfc4647 [CLDR likely-subtags]: http://www.unicode.org/cldr/charts/latest/supplemental/likely_subtags.html [Unicode Locale Identifier]: (http://unicode.org/reports/tr35/#Identifiers) Alternatives ------------ Although Fluent Locale aims to stay close to W3C Accepted Languages, it does not aim to implement the full behavior and some aspects of the language negotiation strategy recommended by W3C, such as weights, are not a target right now. For such purposes, [rust-language-tags][] crate seems to be a better choice. [rust-language-tags]: https://github.com/pyfisch/rust-language-tags Performance ----------- The crate is considered to be fully optimized for production. Develop ------- cargo build cargo test cargo bench fluent-langneg-0.13.0/benches/negotiate.rs010064400017500001731000000021071360773304100166610ustar0000000000000000use criterion::criterion_group; use criterion::criterion_main; use criterion::Criterion; use fluent_langneg::convert_vec_str_to_langids_lossy; use fluent_langneg::negotiate_languages; use unic_langid::LanguageIdentifier; #[no_mangle] #[inline(never)] fn do_negotiate<'a>( requested: &[LanguageIdentifier], available: &'a [LanguageIdentifier], ) -> Vec<&'a LanguageIdentifier> { negotiate_languages( requested, available, None, fluent_langneg::NegotiationStrategy::Filtering, ) } fn negotiate_bench(c: &mut Criterion) { let requested = &["de", "it", "ru"]; let available = &[ "en-US", "fr", "de", "en-GB", "it", "pl", "ru", "sr-Cyrl", "sr-Latn", "zh-Hant", "zh-Hans", "ja-JP", "he-IL", "de-DE", "de-IT", ]; let requested = convert_vec_str_to_langids_lossy(requested); let available = convert_vec_str_to_langids_lossy(available); c.bench_function("negotiate", |b| { b.iter(|| do_negotiate(&requested, &available)) }); } criterion_group!(benches, negotiate_bench); criterion_main!(benches); fluent-langneg-0.13.0/src/accepted_languages.rs010064400017500001731000000026511360773304100176640ustar0000000000000000//! This function parses Accept-Language string into a list of language tags that //! can be later passed to language negotiation functions. //! //! # Example: //! //! ``` //! use fluent_langneg::negotiate_languages; //! use fluent_langneg::NegotiationStrategy; //! use fluent_langneg::parse_accepted_languages; //! use fluent_langneg::convert_vec_str_to_langids_lossy; //! use unic_langid::LanguageIdentifier; //! //! let requested = parse_accepted_languages("de-AT;0.9,de-DE;0.8,de;0.7;en-US;0.5"); //! let available = convert_vec_str_to_langids_lossy(&["fr", "pl", "de", "en-US"]); //! let default: LanguageIdentifier = "en-US".parse().expect("Failed to parse a langid."); //! //! let supported = negotiate_languages( //! &requested, //! &available, //! Some(&default), //! NegotiationStrategy::Filtering //! ); //! //! let expected = convert_vec_str_to_langids_lossy(&["de", "en-US"]); //! assert_eq!(supported, //! expected.iter().map(|t| t.as_ref()).collect::>()); //! ``` //! //! This function ignores the weights associated with the locales, since Fluent Locale //! language negotiation only uses the order of locales, not the weights. //! use unic_langid::LanguageIdentifier; pub fn parse(s: &str) -> Vec { s.split(',') .map(|t| t.trim().split(';').nth(0).unwrap()) .filter(|t| !t.is_empty()) .filter_map(|t| t.parse().ok()) .collect() } fluent-langneg-0.13.0/src/lib.rs010064400017500001731000000032531360773304100146330ustar0000000000000000//! fluent-langneg is an API for operating on locales and language tags. //! It's part of Project Fluent, a localization framework designed to unleash //! the expressive power of the natural language. //! //! The primary use of fluent-langneg is to parse/modify/serialize language tags //! and to perform language negotiation. //! //! fluent-langneg operates on a subset of [BCP47](http://tools.ietf.org/html/bcp47). //! It can parse full BCP47 language tags, and will serialize them back, //! but currently only allows for operations on primary subtags and //! unicode extension keys. //! //! In result fluent-langneg is not suited to replace full implementations of //! BCP47 like [rust-language-tags](https://github.com/pyfisch/rust-language-tags), //! but is arguably a better option for use cases involving operations on //! language tags and for language negotiation. pub mod accepted_languages; pub mod negotiate; pub use accepted_languages::parse as parse_accepted_languages; pub use negotiate::negotiate_languages; pub use negotiate::NegotiationStrategy; use unic_langid::{LanguageIdentifier, LanguageIdentifierError}; pub fn convert_vec_str_to_langids<'a, I, J>( input: I, ) -> Result, LanguageIdentifierError> where I: IntoIterator, J: AsRef<[u8]> + 'a, { input .into_iter() .map(|s| LanguageIdentifier::from_bytes(s.as_ref())) .collect() } pub fn convert_vec_str_to_langids_lossy<'a, I, J>(input: I) -> Vec where I: IntoIterator, J: AsRef<[u8]> + 'a, { input .into_iter() .filter_map(|t| LanguageIdentifier::from_bytes(t.as_ref()).ok()) .collect() } fluent-langneg-0.13.0/src/negotiate/likely_subtags.rs010064400017500001731000000023111365453464700210740ustar0000000000000000use unic_langid::LanguageIdentifier; static REGION_MATCHING_KEYS: &[&str] = &[ "az", "bg", "cs", "de", "es", "fi", "fr", "hu", "it", "lt", "lv", "nl", "pl", "ro", "ru", ]; pub trait MockLikelySubtags { fn maximize(&mut self) -> bool; } impl MockLikelySubtags for LanguageIdentifier { fn maximize(&mut self) -> bool { let extended = match self.to_string().as_str() { "en" => "en-Latn-US", "fr" => "fr-Latn-FR", "sr" => "sr-Cyrl-SR", "sr-RU" => "sr-Latn-SR", "az-IR" => "az-Arab-IR", "zh-GB" => "zh-Hant-GB", "zh-US" => "zh-Hant-US", _ => { let lang = self.language; for subtag in REGION_MATCHING_KEYS { if lang == *subtag { self.region = Some(subtag.parse().unwrap()); return true; } } return false; } }; let langid: LanguageIdentifier = extended.parse().expect("Failed to parse langid."); self.language = langid.language; self.script = langid.script; self.region = langid.region; true } } fluent-langneg-0.13.0/src/negotiate/mod.rs010064400017500001731000000154551365453455500166450ustar0000000000000000//! Language Negotiation is a process in which locales from different //! sources are filtered and sorted in an effort to produce the best //! possible selection of them. //! //! There are multiple language negotiation strategies, most popular is //! described in [RFC4647](https://www.ietf.org/rfc/rfc4647.txt). //! //! The algorithm is based on the BCP4647 3.3.2 Extended Filtering algorithm, //! with several modifications. //! //! # Example: //! //! ``` //! use fluent_langneg::negotiate_languages; //! use fluent_langneg::NegotiationStrategy; //! use fluent_langneg::convert_vec_str_to_langids_lossy; //! use unic_langid::LanguageIdentifier; //! //! let requested = convert_vec_str_to_langids_lossy(&["pl", "fr", "en-US"]); //! let available = convert_vec_str_to_langids_lossy(&["it", "de", "fr", "en-GB", "en_US"]); //! let default: LanguageIdentifier = "en-US".parse().expect("Parsing langid failed."); //! //! let supported = negotiate_languages( //! &requested, //! &available, //! Some(&default), //! NegotiationStrategy::Filtering //! ); //! //! let expected = convert_vec_str_to_langids_lossy(&["fr", "en-US", "en-GB"]); //! assert_eq!(supported, //! expected.iter().map(|t| t.as_ref()).collect::>()); //! ``` //! //! # The exact algorithm is custom, and consists of a 6 level strategy: //! //! ### 1) Attempt to find an exact match for each requested locale in available locales. //! //! Example: //! //! ```text //! // [requested] * [available] = [supported] //! //! ["en-US"] * ["en-US"] = ["en-US"] //! ``` //! //! ### 2) Attempt to match a requested locale to an available locale treated as a locale range. //! //! Example: //! //! ```text //! // [requested] * [available] = [supported] //! //! ["en-US"] * ["en"] = ["en"] //! ^^ //! |-- becomes "en-*-*-*" //! ``` //! //! ### 3) Maximize the requested locale to find the best match in available locales. //! //! This part uses ICU's likelySubtags or similar database. //! //! Example: //! //! ```text //! // [requested] * [available] = [supported] //! //! ["en"] * ["en-GB", "en-US"] = ["en-US"] //! ^^ ^^^^^ ^^^^^ //! | | | //! | |----------- become "en-*-GB-*" and "en-*-US-*" //! | //! |-- ICU likelySubtags expands it to "en-Latn-US" //! ``` //! //! ### 4) Attempt to look up for a different variant of the same locale. //! //! Example: //! //! ```text //! // [requested] * [available] = [supported] //! //! ["ja-JP-win"] * ["ja-JP-mac"] = ["ja-JP-mac"] //! ^^^^^^^^^ ^^^^^^^^^ //! | |-- become "ja-*-JP-mac" //! | //! |----------- replace variant with range: "ja-JP-*" //! ``` //! //! ### 5) Look up for a maximized version of the requested locale, stripped of the region code. //! //! Example: //! //! ```text //! // [requested] * [available] = [supported] //! //! ["en-CA"] * ["en-ZA", "en-US"] = ["en-US", "en-ZA"] //! ^^^^^ //! | ^^^^^ ^^^^^ //! | | | //! | |----------- become "en-*-ZA-*" and "en-*-US-*" //! | //! |----------- strip region produces "en", then lookup likelySubtag: "en-Latn-US" //! ``` //! //! //! ### 6) Attempt to look up for a different region of the same locale. //! //! Example: //! //! ```text //! // [requested] * [available] = [supported] //! //! ["en-GB"] * ["en-AU"] = ["en-AU"] //! ^^^^^ ^^^^^ //! | |-- become "en-*-AU-*" //! | //! |----- replace region with range: "en-*" //! ``` //! use unic_langid::LanguageIdentifier; #[cfg(not(feature = "cldr"))] mod likely_subtags; #[cfg(not(feature = "cldr"))] use likely_subtags::MockLikelySubtags; #[derive(PartialEq, Debug, Clone, Copy)] pub enum NegotiationStrategy { Filtering, Matching, Lookup, } pub fn filter_matches<'a, R: 'a + AsRef, A: 'a + AsRef>( requested: &[R], available: &'a [A], strategy: NegotiationStrategy, ) -> Vec<&'a A> { let mut supported_locales = vec![]; let mut available_locales: Vec<&A> = available.iter().collect(); for req in requested { let mut req = req.as_ref().to_owned(); macro_rules! test_strategy { ($self_as_range:expr, $other_as_range:expr) => {{ let mut match_found = false; available_locales.retain(|locale| { if strategy != NegotiationStrategy::Filtering && match_found { return true; } if locale .as_ref() .matches(&req, $self_as_range, $other_as_range) { match_found = true; supported_locales.push(*locale); return false; } true }); if match_found { match strategy { NegotiationStrategy::Filtering => {} NegotiationStrategy::Matching => continue, NegotiationStrategy::Lookup => break, } } }}; } // 1) Try to find a simple (case-insensitive) string match for the request. test_strategy!(false, false); // 2) Try to match against the available locales treated as ranges. test_strategy!(true, false); // Per Unicode TR35, 4.4 Locale Matching, we don't add likely subtags to // requested locales, so we'll skip it from the rest of the steps. if req.language.is_empty() { continue; } // 3) Try to match against a maximized version of the requested locale if req.maximize() { test_strategy!(true, false); } // 4) Try to match against a variant as a range req.clear_variants(); test_strategy!(true, true); // 5) Try to match against the likely subtag without region req.region = None; if req.maximize() { test_strategy!(true, false); } // 6) Try to match against a region as a range req.region = None; test_strategy!(true, true); } supported_locales } pub fn negotiate_languages< 'a, R: 'a + AsRef, A: 'a + AsRef + PartialEq, >( requested: &[R], available: &'a [A], default: Option<&'a A>, strategy: NegotiationStrategy, ) -> Vec<&'a A> { let mut supported = filter_matches(requested, available, strategy); if let Some(default) = default { if strategy == NegotiationStrategy::Lookup { if supported.is_empty() { supported.push(default); } } else if !supported.contains(&default) { supported.push(default); } } supported }