chore(i18n): initialize new package
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'enums/format.dart';
|
||||
export 'exceptions/exceptions.dart';
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
enum Format {
|
||||
/// JSON i18 file format.
|
||||
json(['json']),
|
||||
|
||||
/// YAML i18 file format.
|
||||
yaml(['yaml', 'yml']),
|
||||
|
||||
/// ARB i18 file format.
|
||||
arb(['arb']);
|
||||
|
||||
const Format(this.extensions);
|
||||
|
||||
final List<String> extensions;
|
||||
|
||||
/// Returns the [Format] that matches the given [ext].
|
||||
static Format? fromExtension(String ext) {
|
||||
for (final format in Format.values) {
|
||||
if (format.extensions.contains(ext)) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Returns the [Format] that matches the given [path].
|
||||
static Format? extensionOf(String path) =>
|
||||
fromExtension(path.split('.').last);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_i18n/src/core/enums/format.dart';
|
||||
|
||||
/// Exception thrown when the i18n file is not found.
|
||||
///
|
||||
/// Source can be a file path or a URL.
|
||||
class SourceNotFoundException extends ClientException {
|
||||
SourceNotFoundException(String source, {required Format format})
|
||||
: super('Source `$source` (format: $format) not found.');
|
||||
}
|
||||
|
||||
/// Exception thrown when the i18n file is not valid.
|
||||
class NoLocaleException extends ClientException {
|
||||
NoLocaleException()
|
||||
: super('No `@@locale` key found in the source nor locale provided.');
|
||||
}
|
||||
|
||||
/// Exception thrown when the key is not found in the i18n file.
|
||||
class KeyNotFoundException extends ClientException {
|
||||
KeyNotFoundException(String key, [Map<String, dynamic> arguments = const {}])
|
||||
: super(
|
||||
'Key `$key` not found. ${arguments.isNotEmpty ? '($arguments)' : ''}',
|
||||
);
|
||||
}
|
||||
|
||||
/// Exception thrown when the searched key requires arguments but none were
|
||||
/// provided.
|
||||
class ArgumentsRequiredException extends ClientException {
|
||||
ArgumentsRequiredException(String key, String value)
|
||||
: super('Key `$key` requires arguments. ($value)');
|
||||
}
|
||||
|
||||
/// Exception thrown when the key references a malformed value.
|
||||
class MalformedValueException extends ClientException {
|
||||
MalformedValueException(String key, String value)
|
||||
: super('Key `$key` references a malformed value. ($value)');
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'data_sources/assets_file_data_source_impl.dart';
|
||||
export 'data_sources/network_data_source_impl.dart';
|
||||
export 'repositories/i18_repository_impl.dart';
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/services.dart' show ServicesBinding, rootBundle;
|
||||
import 'package:wyatt_i18n/src/core/enums/format.dart';
|
||||
import 'package:wyatt_i18n/src/core/exceptions/exceptions.dart';
|
||||
import 'package:wyatt_i18n/src/domain/data_sources/i18n_data_source.dart';
|
||||
|
||||
class AssetsFileDataSourceImpl extends I18nDataSource {
|
||||
const AssetsFileDataSourceImpl({super.format = Format.arb}) : super();
|
||||
|
||||
/// Checks if the given [assetPath] is a local asset.
|
||||
Future<bool> assetExists(String assetPath) async {
|
||||
final encoded = utf8.encoder.convert(
|
||||
Uri(path: Uri.encodeFull(assetPath)).path,
|
||||
);
|
||||
final asset = await ServicesBinding.instance.defaultBinaryMessenger
|
||||
.send('flutter/assets', encoded.buffer.asByteData());
|
||||
|
||||
return asset != null;
|
||||
}
|
||||
|
||||
Future<String?> _tryLoad(String basePath) async {
|
||||
String? content;
|
||||
try {
|
||||
for (final ext in super.format.extensions) {
|
||||
if (await assetExists('$basePath.$ext')) {
|
||||
content = await rootBundle.loadString('$basePath.$ext');
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
throw SourceNotFoundException(basePath, format: format);
|
||||
}
|
||||
|
||||
if (content == null) {
|
||||
throw SourceNotFoundException(basePath, format: format);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
Future<String> _load(String locale) async {
|
||||
String? content;
|
||||
|
||||
try {
|
||||
content = await _tryLoad('assets/i18n.$locale');
|
||||
} catch (_) {
|
||||
content = await _tryLoad('assets/i18n');
|
||||
}
|
||||
|
||||
/// Content can't be null at this point.
|
||||
/// Because if it is, previous [_tryLoad] calls would have t
|
||||
/// hrown an exception.
|
||||
return content!;
|
||||
}
|
||||
|
||||
/// Loads the i18n file from Assets folder.
|
||||
///
|
||||
/// The i18n file must be named `i18n.<locale>.<extension>` and must
|
||||
/// be specified in the `pubspec.yaml` file.
|
||||
@override
|
||||
Future<String> load(String locale) async {
|
||||
final content = await _load(locale);
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_i18n/src/core/enums/format.dart';
|
||||
import 'package:wyatt_i18n/src/domain/data_sources/i18n_data_source.dart';
|
||||
|
||||
class NetworkDataSourceImpl extends I18nDataSource {
|
||||
const NetworkDataSourceImpl({super.format = Format.arb}) : super();
|
||||
|
||||
@override
|
||||
Future<String> load(String locale) {
|
||||
// TODO(wyatt): implement load from network
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_i18n/src/domain/data_sources/i18n_data_source.dart';
|
||||
import 'package:wyatt_i18n/src/domain/entities/i18n.dart';
|
||||
import 'package:wyatt_i18n/src/domain/repositories/i18n_repository.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
class I18RepositoryImpl extends I18nRepository {
|
||||
const I18RepositoryImpl({
|
||||
required this.dataSource,
|
||||
}) : super();
|
||||
|
||||
final I18nDataSource dataSource;
|
||||
|
||||
@override
|
||||
FutureOrResult<I18n> load(String locale) async =>
|
||||
await Result.tryCatchAsync<I18n, AppException, AppException>(
|
||||
() async {
|
||||
final content = await dataSource.load(locale);
|
||||
// TODO: Parse the content into a Map<String, dynamic> and return it.
|
||||
|
||||
return I18n(locale: locale,
|
||||
unparsedData: content,
|
||||
data: {},);
|
||||
},
|
||||
(error) => error,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_i18n/src/core/enums/format.dart';
|
||||
|
||||
/// Base class for i18n data sources.
|
||||
///
|
||||
/// This class is used to load i18n files from a source.
|
||||
/// It returns a [Future] that resolves to a [String] containing the i18n file
|
||||
/// contents.
|
||||
abstract class I18nDataSource extends BaseDataSource {
|
||||
const I18nDataSource({this.format = Format.arb});
|
||||
|
||||
final Format format;
|
||||
|
||||
/// Loads the i18n file from the source.
|
||||
Future<String> load(String locale);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'data_sources/i18n_data_source.dart';
|
||||
export 'entities/i18n.dart';
|
||||
export 'repositories/i18n_repository.dart';
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
|
||||
/// Data structure for i18n files.
|
||||
class I18n extends Entity {
|
||||
const I18n({
|
||||
required this.locale,
|
||||
required this.unparsedData,
|
||||
required this.data,
|
||||
}) : super();
|
||||
|
||||
/// The locale of the i18n file.
|
||||
final String locale;
|
||||
|
||||
/// The unparsed data of the i18n file.
|
||||
final String unparsedData;
|
||||
|
||||
/// The data of the i18n file.
|
||||
final Map<String, dynamic> data;
|
||||
|
||||
String operator [](String key) {
|
||||
final value = data[key];
|
||||
|
||||
if (value is String) {
|
||||
return value;
|
||||
} else {
|
||||
throw Exception('Invalid i18n key: $key');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_i18n/src/domain/entities/i18n.dart';
|
||||
|
||||
/// Base class for i18n repositories.
|
||||
abstract class I18nRepository extends BaseRepository {
|
||||
const I18nRepository() : super();
|
||||
|
||||
/// Loads the i18n file from the source.
|
||||
FutureOrResult<I18n> load(String locale);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'core/core.dart';
|
||||
export 'data/data.dart';
|
||||
export 'domain/domain.dart';
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
abstract class WyattI18n {
|
||||
static String get testString => 'Package: Wyatt I18n';
|
||||
}
|
||||
Reference in New Issue
Block a user