Home | History | Annotate | Download | only in src
      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.
     45   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".
     97   const std::string& GetKey() const { return key_; }
     98 
     99   // Returns the name for this rule. For example, the name for "TX" is "Texas".
    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".
    104   const std::string& GetLatinName() const { return latin_name_; }
    105 
    106   // Returns the format of the address as it should appear on an envelope.
    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.
    113   const std::vector<std::vector<FormatElement> >& GetLatinFormat() const {
    114     return latin_format_;
    115   }
    116 
    117   // Returns the required fields for this rule.
    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.
    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"].
    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"].
    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".
    137   const std::string& GetLanguage() const { return language_; }
    138 
    139   // Returns the postal code format, for example "\\d{5}([ \\-]\\d{4})?".
    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".
    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".
    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