blob: 3a941ebb4962c11a6dcd56898966cb780fbb67f9 [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'locale/locale_implementation.dart';
import 'locale/locale_parser.dart' show LocaleParser;
/// A representation of a [Unicode Locale
/// Identifier](https://www.unicode.org/reports/tr35/#Unicode_locale_identifier).
///
/// To create Locale instances, consider using:
/// * [fromSubtags] for language, script and region,
/// * [parse] for Unicode Locale Identifier strings (throws exceptions on
/// failure),
/// * [tryParse] for Unicode Locale Identifier strings (returns null on
/// failure).
abstract class Locale {
/// Constructs a Locale instance that consists of only language, script and
/// region subtags.
///
/// Throws a [FormatException] if any subtag is syntactically invalid.
static Locale fromSubtags(
{String languageCode, String scriptCode, String countryCode}) =>
LocaleImplementation.fromSubtags(
languageCode: languageCode,
scriptCode: scriptCode,
countryCode: countryCode);
/// Parses [Unicode Locale Identifiers][localeIds] to produce [Locale]
/// instances.
///
/// [localeIds]:
/// https://www.unicode.org/reports/tr35/#Unicode_locale_identifier
///
/// Throws a [FormatException] if [localeIdentifier] is syntactically invalid.
static Locale parse(String localeIdentifier) {
assert(localeIdentifier != null);
var parser = LocaleParser(localeIdentifier);
var locale = parser.toLocale();
if (locale == null) {
throw FormatException('Locale "$localeIdentifier": '
'${parser.problems.join("; ")}.');
}
return locale;
}
/// Parses [Unicode Locale Identifiers][localeIds] to produce [Locale]
/// instances.
///
/// [localeIds]:
/// https://www.unicode.org/reports/tr35/#Unicode_locale_identifier
///
/// Returns `null` if [localeIdentifier] is syntactically invalid.
static Locale tryParse(String localeIdentifier) {
assert(localeIdentifier != null);
var parser = LocaleParser(localeIdentifier);
return parser.toLocale();
}
/// The language subtag of the Locale Identifier.
///
/// It is syntactically valid, normalized (has correct case) and canonical
/// (deprecated tags have been replaced), but not necessarily valid (the
/// language might not exist) because the list of valid languages changes with
/// time.
String get languageCode;
/// The script subtag of the Locale Identifier, null if absent.
///
/// It is syntactically valid and normalized (has correct case), but not
/// necessarily valid (the script might not exist) because the list of valid
/// scripts changes with time.
String get scriptCode;
/// The region subtag of the Locale Identifier, null if absent.
///
/// It is syntactically valid, normalized (has correct case) and canonical
/// (deprecated tags have been replaced), but not necessarily valid (the
/// region might not exist) because the list of valid regions changes with
/// time.
String get countryCode;
/// Iterable of variant subtags.
///
/// They are syntactically valid, normalized (have correct case) and sorted
/// alphabetically, but not necessarily valid (variants might not exist)
/// because the list of variants changes with time.
Iterable<String> get variants;
/// Returns the canonical [Unicode BCP47 Locale
/// Identifier](http://www.unicode.org/reports/tr35/#BCP_47_Conformance) for
/// this locale.
String toLanguageTag();
/// Returns the canonical [Unicode BCP47 Locale
/// Identifier](http://www.unicode.org/reports/tr35/#BCP_47_Conformance) for
/// this locale.
@override
String toString() => toLanguageTag();
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Locale && this.toLanguageTag() == other.toLanguageTag();
}
@override
int get hashCode {
return toLanguageTag().hashCode;
}
}