1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! A crate for parsing CLDR plural rules.
//!
//! This crate parses plural rules and returns an AST representation of the rule. Plural rules must be written according to the specifications outlined at [Unicode's website](http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules).
//!
//! Plural rules, compatible with this crate, can be found at [this GitHub repository](https://github.com/unicode-cldr/cldr-core/blob/master/supplemental/plurals.json).
//!
//! # Examples
//!
//! ```
//! use cldr_pluralrules_parser::parse_plural_rule;
//! use cldr_pluralrules_parser::ast::*;
//!
//! let condition = Condition(vec![
//!     AndCondition(vec![Relation {
//!         expression: Expression {
//!             operand: Operand('i'),
//!             modulus: None,
//!         },
//!         operator: Operator::Is,
//!         range_list: RangeList(vec![RangeListItem::Value(Value(5))]),
//!     }]),
//!     AndCondition(vec![Relation {
//!         expression: Expression {
//!             operand: Operand('v'),
//!             modulus: None,
//!         },
//!         operator: Operator::Within,
//!         range_list: RangeList(vec![RangeListItem::Value(Value(2))]),
//!     }]),
//! ]);
//!
//! assert_eq!(condition, parse_plural_rule("i is 5 or v within 2"))
//! ```

#[macro_use]
extern crate nom;

/// A public AST module for plural rule representations.
pub mod ast;
/// A private parsing module for plural rules.
mod parser;

use crate::ast::*;
use crate::parser::*;
use nom::types::CompleteStr;

/// Given a string reference of a plural rule, will return the AST representation of that rule.
///
/// # Examples
///
/// ```
/// use cldr_pluralrules_parser::parse_plural_rule;
/// use cldr_pluralrules_parser::ast::*;
///
/// let condition = Condition(vec![
///     AndCondition(vec![Relation {
///         expression: Expression {
///             operand: Operand('i'),
///             modulus: None,
///         },
///         operator: Operator::Is,
///         range_list: RangeList(vec![RangeListItem::Value(Value(5))]),
///     }]),
///     AndCondition(vec![Relation {
///         expression: Expression {
///             operand: Operand('v'),
///             modulus: None,
///         },
///         operator: Operator::Within,
///         range_list: RangeList(vec![RangeListItem::Value(Value(2))]),
///     }]),
/// ]);
///
/// assert_eq!(condition, parse_plural_rule("i is 5 or v within 2"))
/// ```
pub fn parse_plural_rule(source: &str) -> Condition {
    parse_rule(CompleteStr(source)).unwrap().1
}