• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2013 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // An object to store validation rules.
16 
17 #ifndef I18N_ADDRESSINPUT_RULE_H_
18 #define I18N_ADDRESSINPUT_RULE_H_
19 
20 #include <libaddressinput/address_field.h>
21 #include <libaddressinput/util/basictypes.h>
22 
23 #include <string>
24 #include <vector>
25 
26 namespace i18n {
27 namespace addressinput {
28 
29 class Json;
30 
31 // Stores an element in the format of an address as it should be displayed on an
32 // envelope. The element can be either a literal string, like " ", or a field,
33 // like ADMIN_AREA.
34 struct FormatElement {
35   // Builds an element of address format for |field|.
36   explicit FormatElement(AddressField field);
37 
38   // Builds an element of address format for |literal|. The literal should not
39   // be empty.
40   explicit FormatElement(const std::string& literal);
41 
42   ~FormatElement();
43 
44   // Returns true if this is a field element.
IsFieldFormatElement45   bool IsField() const { return literal.empty(); }
46 
47   bool operator==(const FormatElement& other) const;
48 
49   // The field for this element in address format. Should be used only if
50   // |literal| is an empty string.
51   AddressField field;
52 
53   // The literal string for this element in address format. If empty, then this
54   // is a field element.
55   std::string literal;
56 };
57 
58 // Stores the validation, input, and display rules for an address. Sample usage:
59 //    Rule rule;
60 //    if (rule.ParseSerializedRule("{\"fmt\": \"%A%n%C%S %Z\"}")) {
61 //      Process(rule.GetFormat());
62 //    }
63 class Rule {
64  public:
65   // The types of fields that describe the rule.
66   enum IdentityField {
67     KEY,
68     NAME,
69     LATIN_NAME,
70     IDENTITY_FIELDS_SIZE
71   };
72 
73   Rule();
74   ~Rule();
75 
76   // Returns the default rule at a country level. If a country does not specify
77   // address format, for example, then the format from this rule should be used
78   // instead.
79   static const Rule& GetDefault();
80 
81   // Copies all data from |rule|.
82   void CopyFrom(const Rule& rule);
83 
84   // Parses |serialized_rule|. Returns |true| if the |serialized_rule| has valid
85   // format (JSON dictionary).
86   bool ParseSerializedRule(const std::string& serialized_rule);
87 
88   // Parses |json_rule|, which must contain parsed serialized rule.
89   void ParseJsonRule(const Json& json_rule);
90 
91   // Returns the value of the |identity_field| for this rule, for example, can
92   // return "TX" or "Texas". The |identity_field| parameter should not be
93   // IDENTITY_FIELDS_SIZE.
94   const std::string& GetIdentityField(IdentityField identity_field) const;
95 
96   // Returns the key for this rule. For example, can return "TX".
GetKey()97   const std::string& GetKey() const { return key_; }
98 
99   // Returns the name for this rule. For example, the name for "TX" is "Texas".
GetName()100   const std::string& GetName() const { return name_; }
101 
102   // Returns the latinized version of the name. For example, the latinized
103   // version of "北京市" is "Beijing Shi".
GetLatinName()104   const std::string& GetLatinName() const { return latin_name_; }
105 
106   // Returns the format of the address as it should appear on an envelope.
GetFormat()107   const std::vector<std::vector<FormatElement> >& GetFormat() const {
108     return format_;
109   }
110 
111   // Returns the latinized format of the address as it should appear on an
112   // envelope.
GetLatinFormat()113   const std::vector<std::vector<FormatElement> >& GetLatinFormat() const {
114     return latin_format_;
115   }
116 
117   // Returns the required fields for this rule.
GetRequired()118   const std::vector<AddressField>& GetRequired() const { return required_; }
119 
120   // Returns the sub-keys for this rule, which are the administrative areas of a
121   // country, the localities of an administrative area, or the dependent
122   // localities of a locality. For example, the rules for "US" have sub-keys of
123   // "CA", "NY", "TX", etc.
GetSubKeys()124   const std::vector<std::string>& GetSubKeys() const { return sub_keys_; }
125 
126   // Returns all of the language codes for which this rule has custom rules, for
127   // example ["de", "fr", "it"].
GetLanguages()128   const std::vector<std::string>& GetLanguages() const { return languages_; }
129 
130   // Returns all of the languages codes for addresses that adhere to this rule,
131   // for example ["de", "fr", "gsw", "it"].
GetInputLanguages()132   const std::vector<std::string>& GetInputLanguages() const {
133     return input_languages_;
134   }
135 
136   // Returns the language code of this rule, for example "de".
GetLanguage()137   const std::string& GetLanguage() const { return language_; }
138 
139   // Returns the postal code format, for example "\\d{5}([ \\-]\\d{4})?".
GetPostalCodeFormat()140   const std::string& GetPostalCodeFormat() const { return postal_code_format_; }
141 
142   // A string identifying the type of admin area name for this country, e.g.
143   // "state", "province", or "district".
GetAdminAreaNameType()144   const std::string& GetAdminAreaNameType() const {
145     return admin_area_name_type_;
146   }
147 
148   // A string identifying the type of postal code name for this country, either
149   // "postal" or "zip".
GetPostalCodeNameType()150   const std::string& GetPostalCodeNameType() const {
151     return postal_code_name_type_;
152   }
153 
154   // Outputs the sub key for a given user input. For example, Texas will map to
155   // TX.
156   //
157   // If |keep_input_latin| is true, then does not convert a latinized region
158   // name into a sub key. For example, tOKYo will change to TOKYO. If
159   // |keep_input_latin| is false, then converts a latinized region name into a
160   // sub key. For example, tOKYo becomes 東京都.
161   //
162   // |sub_key| should not be NULL.
163   bool CanonicalizeSubKey(const std::string& user_input,
164                           bool keep_input_latin,
165                           std::string* sub_key) const;
166 
167  private:
168   std::string key_;
169   std::string name_;
170   std::string latin_name_;
171   std::vector<std::vector<FormatElement> > format_;
172   std::vector<std::vector<FormatElement> > latin_format_;
173   std::vector<AddressField> required_;
174   std::vector<std::string> sub_keys_;
175   std::vector<std::string> sub_names_;
176   // The Latin names (when |sub_names_| is not in Latin characters).
177   std::vector<std::string> sub_lnames_;
178   std::vector<std::string> languages_;
179   std::vector<std::string> input_languages_;
180   std::string language_;
181   std::string postal_code_format_;
182   std::string admin_area_name_type_;
183   std::string postal_code_name_type_;
184 
185   DISALLOW_COPY_AND_ASSIGN(Rule);
186 };
187 
188 }  // namespace addressinput
189 }  // namespace i18n
190 
191 #endif  // I18N_ADDRESSINPUT_RULE_H_
192