mirror of
https://github.com/EasyTier/astral.git
synced 2025-05-19 10:30:24 +00:00
196 lines
5.2 KiB
Dart
196 lines
5.2 KiB
Dart
import 'dart:io';
|
|
import 'package:yaml/yaml.dart';
|
|
|
|
class ConfigManager {
|
|
final String filePath;
|
|
final Map<String, dynamic> defaultConfig;
|
|
late Map<String, dynamic> _config;
|
|
|
|
ConfigManager({
|
|
required this.filePath,
|
|
required this.defaultConfig,
|
|
}) : _config = Map.from(defaultConfig);
|
|
|
|
/// 加载配置文件(如果不存在则创建默认配置)
|
|
Future<void> load() async {
|
|
final file = File(filePath);
|
|
|
|
if (!await file.exists()) {
|
|
await _createDefaultConfig();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final content = await file.readAsString();
|
|
final yamlMap = loadYaml(content);
|
|
_config = _mergeConfigs(_convertYaml(yamlMap));
|
|
} catch (e) {
|
|
// 提供更详细的错误信息并使用默认配置
|
|
print('配置文件解析失败: $e');
|
|
print('将使用默认配置继续运行。请检查配置文件格式是否正确。');
|
|
_config = Map.from(defaultConfig);
|
|
}
|
|
}
|
|
|
|
/// 保存当前配置到文件
|
|
Future<void> save() async {
|
|
final yamlString = _generateYaml();
|
|
await File(filePath).writeAsString(yamlString);
|
|
}
|
|
|
|
/// 获取配置值(支持点分隔符访问嵌套字段)
|
|
T? get<T>(String keyPath) {
|
|
final keys = keyPath.split('.');
|
|
dynamic value = _config;
|
|
|
|
for (final key in keys) {
|
|
if (value is Map && value.containsKey(key)) {
|
|
value = value[key];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return value is T ? value : null;
|
|
}
|
|
|
|
/// 设置配置值(支持点分隔符访问嵌套字段)
|
|
void set<T>(String keyPath, T value) {
|
|
final keys = keyPath.split('.');
|
|
dynamic current = _config;
|
|
|
|
for (int i = 0; i < keys.length - 1; i++) {
|
|
final key = keys[i];
|
|
current = current.putIfAbsent(key, () => <String, dynamic>{});
|
|
}
|
|
|
|
// 类型转换确保值类型兼容性
|
|
if (value is Map<String, dynamic>) {
|
|
current[keys.last] = Map<String, Object>.from(value);
|
|
} else if (value is List<Map<String, dynamic>>) {
|
|
current[keys.last] =
|
|
value.map((e) => Map<String, Object>.from(e)).toList();
|
|
} else {
|
|
current[keys.last] = value;
|
|
}
|
|
}
|
|
|
|
/// 合并用户配置与默认配置
|
|
Map<String, dynamic> _mergeConfigs(Map<String, dynamic> userConfig) {
|
|
return _deepMerge(defaultConfig, userConfig);
|
|
}
|
|
|
|
/// 深度合并两个Map
|
|
Map<String, dynamic> _deepMerge(
|
|
Map<String, dynamic> base, Map<String, dynamic> override) {
|
|
final result = Map<String, dynamic>.from(base);
|
|
|
|
override.forEach((key, value) {
|
|
if (value is Map<String, dynamic> &&
|
|
result[key] is Map<String, dynamic>) {
|
|
result[key] = _deepMerge(result[key], value);
|
|
} else {
|
|
result[key] = value;
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
/// 转换YAML结构为Dart Map
|
|
dynamic _convertYaml(dynamic yaml) {
|
|
if (yaml is YamlMap) {
|
|
return yaml.map((k, v) => MapEntry(k.toString(), _convertYaml(v)));
|
|
}
|
|
if (yaml is YamlList) {
|
|
return yaml.map((e) => _convertYaml(e)).toList();
|
|
}
|
|
return yaml;
|
|
}
|
|
|
|
/// 生成YAML字符串
|
|
String _generateYaml() {
|
|
final buffer = StringBuffer();
|
|
_writeMap(_config, buffer, 0);
|
|
return buffer.toString();
|
|
}
|
|
|
|
/// 递归写入Map结构
|
|
void _writeMap(Map<String, dynamic> map, StringBuffer buffer, int indent) {
|
|
final prefix = ' ' * indent;
|
|
|
|
map.forEach((key, value) {
|
|
buffer.write('$prefix$key: ');
|
|
|
|
if (value is Map<String, dynamic>) {
|
|
buffer.writeln();
|
|
_writeMap(value, buffer, indent + 1);
|
|
} else if (value is List) {
|
|
_writeList(value, buffer, indent + 1);
|
|
} else {
|
|
buffer.writeln(_formatValue(value));
|
|
}
|
|
});
|
|
}
|
|
|
|
/// 处理列表值
|
|
void _writeList(List list, StringBuffer buffer, int indent) {
|
|
final prefix = ' ' * indent;
|
|
|
|
if (list.isEmpty) {
|
|
buffer.writeln('[]');
|
|
return;
|
|
}
|
|
|
|
buffer.writeln();
|
|
for (final item in list) {
|
|
buffer.write('$prefix- ');
|
|
if (item is Map) {
|
|
if (item.isEmpty) {
|
|
buffer.writeln('{}');
|
|
} else {
|
|
buffer.writeln();
|
|
// 注意这里使用了正确的缩进级别
|
|
_writeMapInList(item.cast<String, dynamic>(), buffer, indent + 1);
|
|
}
|
|
} else if (item is List) {
|
|
_writeList(item, buffer, indent + 1);
|
|
} else {
|
|
buffer.writeln(_formatValue(item));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 专门用于处理列表中的Map项,确保正确缩进
|
|
void _writeMapInList(
|
|
Map<String, dynamic> map, StringBuffer buffer, int indent) {
|
|
final prefix = ' ' * indent;
|
|
|
|
map.forEach((key, value) {
|
|
buffer.write('$prefix$key: ');
|
|
|
|
if (value is Map<String, dynamic>) {
|
|
buffer.writeln();
|
|
_writeMap(value, buffer, indent + 1);
|
|
} else if (value is List) {
|
|
_writeList(value, buffer, indent + 1);
|
|
} else {
|
|
buffer.writeln(_formatValue(value));
|
|
}
|
|
});
|
|
}
|
|
|
|
/// 格式值处理
|
|
String _formatValue(dynamic value) {
|
|
if (value is String) return '"$value"';
|
|
if (value is bool) return value.toString();
|
|
return value.toString();
|
|
}
|
|
|
|
/// 创建默认配置文件
|
|
Future<void> _createDefaultConfig() async {
|
|
_config = Map.from(defaultConfig);
|
|
await save();
|
|
}
|
|
}
|