Skip to content

Commit

Permalink
Expand module docs for context, resolve and types.
Browse files Browse the repository at this point in the history
  • Loading branch information
stasm committed Oct 13, 2017
1 parent 51f5797 commit edfde4b
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 50 deletions.
52 changes: 21 additions & 31 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
//! Context is a collection of localization messages in Fluent.
//! `MessageContext` is a collection of localization messages in Fluent.
//!
//! It stores a list of messages in a single locale which can reference one another,
//! use same internationalization formatters, functions, environmental variables
//! and are expected to be used together.
//!
//! The main structure is called `MessageContext`.
//! It stores a list of messages in a single locale which can reference one another, use the same
//! internationalization formatters, functions, environmental variables and are expected to be used
//! together.

use std::collections::HashMap;

Expand All @@ -13,40 +11,32 @@ use super::syntax::parse;
use super::types::FluentValue;
use super::resolve::{Env, ResolveValue};

/// MessageContext is a collection of localization messages that are meant to
/// be used together in a single localization context.
///
/// An example of such structure is a single UI widget, panel or view.
///
/// # MessageContext life-cycle
///
/// To create a context, call `MessageContext::new` with a locale list that
/// represents the best possible fallback chain for a given locale.
/// The simplest case is a one-locale list.
/// `MessageContext` is a collection of localization messages which are meant to be used together
/// in a single view, widget or any other UI abstraction.
///
/// Next, call `add_messages` one or more times, providing it with a list
/// of localization messages formatted using FTL syntax.
/// # `MessageContext` Life-cycle
///
/// From that moment, the `MessageContext` object is ready to be used for localization.
/// To create a context, call `MessageContext::new` with a locale list that represents the best
/// possible fallback chain for a given locale. The simplest case is a one-locale list.
///
/// At any point when a translation is neeeded, call `get_message` to retrieve a
/// `fluent::context::Message` structure and then `format` within the context.
/// Next, call `add_messages` one or more times, supplying translations in the FTL syntax. The
/// `MessageContext` instance is now ready to be used for localization.
///
/// The result is always a single string that should be displayed in the UI.
/// Like all internationalization operations, the resulting string is not to
/// be examined for testing purposes or altered before displaying in anyway.
/// To format a translation, call `get_message` to retrieve a `fluent::context::Message` structure
/// and then `format` it within the context.
///
/// It is recommended to treat such string as opaque from the perspective of the
/// program and use it only to display localized messages.
/// The result is an Option warpping a single string that should be displayed in the UI. It is
/// recommended to treat the result as opaque from the perspective of the program and use it only
/// to display localized messages. Do not examine it or alter in any way before displaying. This
/// is a general good practice as far as all internationalization operations are concerned.
///
///
/// # Locale Fallback Chain
///
/// MessageContext stores messages in a single locale, but keeps a locale
/// fallback chain for language negotaition with internationalization formatters
/// purposes. For example if date and time formatting is impossible in the main
/// language, MessageContext can negotiate with date and time internationalization
/// formatter to use a sensible fallback locale based on the fallback chain.
/// `MessageContext` stores messages in a single locale, but keeps a locale fallback chain for the
/// purpose of language negotiation with i18n formatters. For instance, if date and time formatting
/// are not available in the first locale, `MessageContext` will use its `locales` fallback chain
/// to negotiate a sensible fallback for date and time formatting.
#[allow(dead_code)]
pub struct MessageContext<'ctx> {
pub locales: &'ctx [&'ctx str],
Expand Down
28 changes: 14 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

//! Fluent is a localization system designed to improve how software is translated.
//!
//! The Rust implementation is providing the low level components for syntax
//! operations, like parser and AST, and core localization struct - `MessageContext`.
//! The Rust implementation provides the low level components for syntax operations, like parser
//! and AST, and the core localization struct - `MessageContext`.
//!
//! `MessageContext` is the low level container for storing and formating localization
//! messages. It is expected that implementations will build on top of it by
//! providing language negotiation between user requested languages and available
//! resources and I/O for loading selected resources.
//! `MessageContext` is the low level container for storing and formating localization messages. It
//! is expected that implementations will build on top of it by providing language negotiation
//! between user requested languages and available resources and I/O for loading selected
//! resources.
//!
//! # Example
//!
Expand All @@ -20,25 +20,25 @@
//!
//! let mut ctx = MessageContext::new(&["en-US"]);
//!
//! ctx.add_messages(r#"
//!
//! hello-world = Hello World!
//! intro = Welcome, { $name }
//!
//! "#);
//! ctx.add_messages(
//! "
//! hello-world = Hello, world!
//! intro = Welcome, { $name }.
//! "
//! );
//!
//! let msg = ctx.get_message("hello-world").unwrap();
//! let value = ctx.format(msg, None).unwrap();
//!
//! assert_eq!(value, "Hello World!");
//! assert_eq!(value, "Hello, world!");
//!
//! let mut args = HashMap::new();
//! args.insert("name", FluentValue::from("John"));
//!
//! let msg = ctx.get_message("intro").unwrap();
//! let value = ctx.format(msg, Some(&args)).unwrap();
//!
//! assert_eq!(value, "Welcome, John");
//! assert_eq!(value, "Welcome, John.");
//! ```

pub mod syntax;
Expand Down
14 changes: 10 additions & 4 deletions src/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Resolve module evaluates Fluent values and resolves them
//! The `ResolveValue` trait resolves Fluent AST nodes to [`FluentValues`].
//!
//! This is mostly an internal API used by MessageContext to evaluate
//! Messages and resolve them using context variables and developer
//! arguments.
//! This is an internal API used by [`MessageContext`] to evaluate Messages, Attributes and other
//! AST nodes to [`FluentValues`] which can be then formatted to strings.
//!
//! [`FluentValues`]: ../types/enum.FluentValue.html
//! [`MessageContext`]: ../context/struct.MessageContext.html

use std::collections::HashMap;
use std::str::FromStr;
Expand All @@ -11,11 +13,15 @@ use super::types::FluentValue;
use super::syntax::ast;
use super::context::MessageContext;

/// State for a single `ResolveValue::to_value` call.
pub struct Env<'env> {
/// The current `MessageContext` instance.
pub ctx: &'env MessageContext<'env>,
/// The current arguments passed by the developer.
pub args: Option<&'env HashMap<&'env str, FluentValue>>,
}

/// Converts an AST node to a `FluentValue`.
pub trait ResolveValue {
fn to_value(&self, env: &Env) -> Option<FluentValue>;
}
Expand Down
16 changes: 15 additions & 1 deletion src/types.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
//! Primitive types used by Fluent as arguments for formatting.
//! The `FluentValue` enum represents values which can be formatted to a String.
//!
//! The [`ResolveValue`][] trait from the [`resolve`][] module evaluates AST nodes into
//! `FluentValues` which can then be formatted to Strings using the i18n formatters stored by the
//! `MessageContext` instance if required.
//!
//! The arguments `HashMap` passed to [`MessageContext::format`][] should also use `FluentValues`
//! as values of arguments.
//!
//! [`ResolveValue`]: ../resolve/trait.ResolveValue.html
//! [`resolve`]: ../resolve
//! [`MessageContext::format`]: ../context/struct.MessageContext.html#method.format

use std::f32;
use std::boxed::FnBox;

use super::context::MessageContext;

/// Value types which can be formatted to a String.
#[derive(Clone, Debug, PartialEq)]
pub enum FluentValue {
/// Fluent String type.
String(String),
/// Fluent Number type.
Number(f32),
}

Expand Down

0 comments on commit edfde4b

Please sign in to comment.