From ac018da3e1fe377254449924d4da56e1041eedef Mon Sep 17 00:00:00 2001 From: Prerak Mann Date: Tue, 27 Jun 2023 01:07:37 +0530 Subject: [PATCH] Refactor 2 --- lib/src/config_provider/config.dart | 281 ++++++++-------- .../{schema.dart => config_spec.dart} | 304 +++++++++--------- 2 files changed, 299 insertions(+), 286 deletions(-) rename lib/src/config_provider/{schema.dart => config_spec.dart} (64%) diff --git a/lib/src/config_provider/config.dart b/lib/src/config_provider/config.dart index fe0b58e4..1642e82d 100644 --- a/lib/src/config_provider/config.dart +++ b/lib/src/config_provider/config.dart @@ -13,7 +13,7 @@ import 'package:yaml/yaml.dart'; import '../strings.dart' as strings; import 'config_types.dart'; -import 'schema.dart'; +import 'config_spec.dart'; import 'spec_utils.dart'; final _logger = Logger('ffigen.config_provider.config'); @@ -203,7 +203,7 @@ class Config { } /// Returns the root Schema object. - static Schema getsRootSchema() { + static ConfigSpec getsRootSchema() { final configspecs = Config._(filename: null, packageConfig: null); return configspecs._getRootSchema(); } @@ -219,13 +219,13 @@ class Config { } } - Schema _getRootSchema() { - return FixedMapSchema( - keys: [ + ConfigSpec _getRootSchema() { + return FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.llvmPath, - valueSchema: ListSchema( - childSchema: StringSchema(), + valueConfigSpec: ListSchema( + childSchema: StringConfigSpec(), transform: (node) => llvmPathExtractor(node.value), ), defaultValue: (node) => findDylibAtDefaultLocations(), @@ -234,8 +234,8 @@ class Config { FixedMapEntry( key: strings.output, required: true, - valueSchema: OneOfSchema( - childSchemas: [ + valueConfigSpec: OneOfConfigSpec( + childConfigSpecs: [ _filePathStringSchema(), _outputFullSchema(), ], @@ -248,7 +248,7 @@ class Config { )), FixedMapEntry( key: strings.language, - valueSchema: EnumSchema( + valueConfigSpec: EnumConfigSpec( allowedValues: {strings.langC, strings.langObjC}, transform: (node) { if ((node.value == strings.langObjC)) { @@ -267,16 +267,18 @@ class Config { FixedMapEntry( key: strings.headers, required: true, - valueSchema: FixedMapSchema>( - keys: [ + valueConfigSpec: FixedMapConfigSpec>( + entries: [ FixedMapEntry( key: strings.entryPoints, - valueSchema: ListSchema(childSchema: StringSchema()), + valueConfigSpec: + ListSchema(childSchema: StringConfigSpec()), required: true, ), FixedMapEntry( key: strings.includeDirectives, - valueSchema: ListSchema(childSchema: StringSchema()), + valueConfigSpec: + ListSchema(childSchema: StringConfigSpec()), ), ], transform: (node) => headersExtractor(node.value, filename), @@ -284,12 +286,12 @@ class Config { )), FixedMapEntry( key: strings.compilerOpts, - valueSchema: OneOfSchema>( - childSchemas: [ - StringSchema( + valueConfigSpec: OneOfConfigSpec>( + childConfigSpecs: [ + StringConfigSpec( transform: (node) => [node.value], ), - ListSchema(childSchema: StringSchema()) + ListSchema(childSchema: StringConfigSpec()) ], transform: (node) => compilerOptsExtractor(node.value), ), @@ -298,15 +300,15 @@ class Config { ), FixedMapEntry( key: strings.compilerOptsAuto, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.macos, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.includeCStdLib, - valueSchema: BoolSchema(), + valueConfigSpec: BoolConfigSpec(), defaultValue: (node) => true, ) ], @@ -322,9 +324,9 @@ class Config { )), FixedMapEntry( key: strings.libraryImports, - valueSchema: DynamicMapSchema( - keyValueSchemas: [ - (keyRegexp: ".*", valueSchema: StringSchema()), + valueConfigSpec: DynamicMapConfigSpec( + keyValueConfigSpecs: [ + (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()), ], customValidation: _libraryImportsPredefinedValidation, transform: (node) => libraryImportsExtractor(node.value.cast()), @@ -335,29 +337,29 @@ class Config { ), FixedMapEntry( key: strings.functions, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ..._memberRenameProperties(), FixedMapEntry( key: strings.symbolAddress, - valueSchema: _includeExcludeObject(), + valueConfigSpec: _includeExcludeObject(), defaultValue: (node) => Includer.excludeByDefault(), ), FixedMapEntry( key: strings.exposeFunctionTypedefs, - valueSchema: _includeExcludeObject(), + valueConfigSpec: _includeExcludeObject(), defaultValue: (node) => Includer.excludeByDefault(), ), FixedMapEntry( key: strings.leafFunctions, - valueSchema: _includeExcludeObject(), + valueConfigSpec: _includeExcludeObject(), defaultValue: (node) => Includer.excludeByDefault(), ), FixedMapEntry( key: strings.varArgFunctions, - valueSchema: _functionVarArgsSchema(), + valueConfigSpec: _functionVarArgsSchema(), defaultValue: (node) => >{}, resultOrDefault: (node) { _varArgFunctions = makeVarArgFunctionsMapping( @@ -377,19 +379,19 @@ class Config { )), FixedMapEntry( key: strings.structs, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ..._memberRenameProperties(), _dependencyOnlyFixedMapKey(), FixedMapEntry( key: strings.structPack, - valueSchema: DynamicMapSchema( - keyValueSchemas: [ + valueConfigSpec: DynamicMapConfigSpec( + keyValueConfigSpecs: [ ( keyRegexp: '.*', - valueSchema: EnumSchema( + valueConfigSpec: EnumConfigSpec( allowedValues: {'none', 1, 2, 4, 8, 16}, transform: (node) => node.value == 'none' ? null : node.value, @@ -413,8 +415,8 @@ class Config { )), FixedMapEntry( key: strings.unions, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ..._memberRenameProperties(), @@ -429,8 +431,8 @@ class Config { )), FixedMapEntry( key: strings.enums, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ..._memberRenameProperties(), @@ -442,8 +444,8 @@ class Config { )), FixedMapEntry( key: strings.unnamedEnums, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ], @@ -454,13 +456,13 @@ class Config { )), FixedMapEntry( key: strings.globals, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), FixedMapEntry( key: strings.symbolAddress, - valueSchema: _includeExcludeObject(), + valueConfigSpec: _includeExcludeObject(), defaultValue: (node) => Includer.excludeByDefault(), ) ], @@ -471,8 +473,8 @@ class Config { )), FixedMapEntry( key: strings.macros, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ], @@ -483,8 +485,8 @@ class Config { )), FixedMapEntry( key: strings.typedefs, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ], @@ -495,14 +497,14 @@ class Config { )), FixedMapEntry( key: strings.objcInterfaces, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ ..._includeExcludeProperties(), ..._renameProperties(), ..._memberRenameProperties(), FixedMapEntry( key: strings.objcModule, - valueSchema: _objcInterfaceModuleObject(), + valueConfigSpec: _objcInterfaceModuleObject(), defaultValue: (node) => ObjCModulePrefixer({}), ) ], @@ -515,12 +517,12 @@ class Config { )), FixedMapEntry( key: strings.import, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.symbolFilesImport, - valueSchema: ListSchema( - childSchema: StringSchema(), + valueConfigSpec: ListSchema( + childSchema: StringConfigSpec(), transform: (node) => symbolFileImportExtractor( node.value, _libraryImports, filename, packageConfig), ), @@ -532,26 +534,26 @@ class Config { )), FixedMapEntry( key: strings.typeMap, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.typeMapTypedefs, - valueSchema: _mappedTypeObject(), + valueConfigSpec: _mappedTypeObject(), defaultValue: (node) => >{}, ), FixedMapEntry( key: strings.typeMapStructs, - valueSchema: _mappedTypeObject(), + valueConfigSpec: _mappedTypeObject(), defaultValue: (node) => >{}, ), FixedMapEntry( key: strings.typeMapUnions, - valueSchema: _mappedTypeObject(), + valueConfigSpec: _mappedTypeObject(), defaultValue: (node) => >{}, ), FixedMapEntry( key: strings.typeMapNativeTypes, - valueSchema: _mappedTypeObject(), + valueConfigSpec: _mappedTypeObject(), defaultValue: (node) => >{}, ), ], @@ -581,31 +583,31 @@ class Config { )), FixedMapEntry( key: strings.excludeAllByDefault, - valueSchema: BoolSchema(), + valueConfigSpec: BoolConfigSpec(), defaultValue: (node) => false, resultOrDefault: (node) => _excludeAllByDefault = node.value as bool, ), FixedMapEntry( key: strings.sort, - valueSchema: BoolSchema(), + valueConfigSpec: BoolConfigSpec(), defaultValue: (node) => false, resultOrDefault: (node) => _sort = node.value as bool, ), FixedMapEntry( key: strings.useSupportedTypedefs, - valueSchema: BoolSchema(), + valueConfigSpec: BoolConfigSpec(), defaultValue: (node) => true, resultOrDefault: (node) => _useSupportedTypedefs = node.value as bool, ), FixedMapEntry( key: strings.comments, - valueSchema: _commentSchema(), + valueConfigSpec: _commentSchema(), defaultValue: (node) => CommentType.def(), resultOrDefault: (node) => _commentType = node.value as CommentType, ), FixedMapEntry( key: strings.name, - valueSchema: _dartClassNameStringSchema(), + valueConfigSpec: _dartClassNameStringSchema(), defaultValue: (node) { _logger.warning( "Prefer adding Key '${node.pathString}' to your config."); @@ -615,7 +617,7 @@ class Config { ), FixedMapEntry( key: strings.description, - valueSchema: _nonEmptyStringSchema(), + valueConfigSpec: _nonEmptyStringSchema(), defaultValue: (node) { _logger.warning( "Prefer adding Key '${node.pathString}' to your config."); @@ -625,25 +627,25 @@ class Config { ), FixedMapEntry( key: strings.preamble, - valueSchema: StringSchema( + valueConfigSpec: StringConfigSpec( result: (node) => _preamble = node.value as String?, )), FixedMapEntry( key: strings.useDartHandle, - valueSchema: BoolSchema(), + valueConfigSpec: BoolConfigSpec(), defaultValue: (node) => true, resultOrDefault: (node) => _useDartHandle = node.value as bool, ), FixedMapEntry( key: strings.ffiNative, - valueSchema: OneOfSchema( - childSchemas: [ - EnumSchema(allowedValues: {null}), - FixedMapSchema( - keys: [ + valueConfigSpec: OneOfConfigSpec( + childConfigSpecs: [ + EnumConfigSpec(allowedValues: {null}), + FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.ffiNativeAsset, - valueSchema: StringSchema(), + valueConfigSpec: StringConfigSpec(), required: true, ) ], @@ -659,7 +661,7 @@ class Config { ); } - bool _libraryImportsPredefinedValidation(SchemaNode node) { + bool _libraryImportsPredefinedValidation(ConfigSpecNode node) { if (node.value is YamlMap) { return (node.value as YamlMap).keys.where((key) { if (strings.predefinedLibraryImports.containsKey(key)) { @@ -673,18 +675,18 @@ class Config { return true; } - OneOfSchema _commentSchema() { - return OneOfSchema( - childSchemas: [ - BoolSchema( + OneOfConfigSpec _commentSchema() { + return OneOfConfigSpec( + childConfigSpecs: [ + BoolConfigSpec( transform: (node) => (node.value == true) ? CommentType.def() : CommentType.none(), ), - FixedMapSchema( - keys: [ + FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.style, - valueSchema: EnumSchema( + valueConfigSpec: EnumConfigSpec( allowedValues: {strings.doxygen, strings.any}, transform: (node) => node.value == strings.doxygen ? CommentStyle.doxygen @@ -694,7 +696,7 @@ class Config { ), FixedMapEntry( key: strings.length, - valueSchema: EnumSchema( + valueConfigSpec: EnumConfigSpec( allowedValues: {strings.brief, strings.full}, transform: (node) => node.value == strings.brief ? CommentLength.brief @@ -712,26 +714,26 @@ class Config { ); } - DynamicMapSchema _functionVarArgsSchema() { - return DynamicMapSchema( - keyValueSchemas: [ + DynamicMapConfigSpec _functionVarArgsSchema() { + return DynamicMapConfigSpec( + keyValueConfigSpecs: [ ( keyRegexp: ".*", - valueSchema: ListSchema( - childSchema: OneOfSchema( - childSchemas: [ - ListSchema(childSchema: StringSchema()), - FixedMapSchema( - keys: [ + valueConfigSpec: ListSchema( + childSchema: OneOfConfigSpec( + childConfigSpecs: [ + ListSchema(childSchema: StringConfigSpec()), + FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.types, - valueSchema: - ListSchema(childSchema: StringSchema()), + valueConfigSpec: + ListSchema(childSchema: StringConfigSpec()), required: true, ), FixedMapEntry( key: strings.postfix, - valueSchema: StringSchema(), + valueConfigSpec: StringConfigSpec(), ), ], ) @@ -744,26 +746,26 @@ class Config { ); } - FixedMapSchema _outputFullSchema() { - return FixedMapSchema( - keys: [ + FixedMapConfigSpec _outputFullSchema() { + return FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.bindings, - valueSchema: _filePathStringSchema(), + valueConfigSpec: _filePathStringSchema(), required: true, ), FixedMapEntry( key: strings.symbolFile, - valueSchema: FixedMapSchema( - keys: [ + valueConfigSpec: FixedMapConfigSpec( + entries: [ FixedMapEntry( key: strings.output, - valueSchema: _filePathStringSchema(), + valueConfigSpec: _filePathStringSchema(), required: true, ), FixedMapEntry( key: strings.importPath, - valueSchema: StringSchema(), + valueConfigSpec: StringConfigSpec(), required: true, ), ], @@ -773,22 +775,22 @@ class Config { ); } - StringSchema _filePathStringSchema() { - return StringSchema( + StringConfigSpec _filePathStringSchema() { + return StringConfigSpec( schemaDefName: 'filePath', schemaDescription: "A file path", ); } - StringSchema _nonEmptyStringSchema() { - return StringSchema( + StringConfigSpec _nonEmptyStringSchema() { + return StringConfigSpec( schemaDefName: 'nonEmptyString', pattern: r'.+', ); } - StringSchema _dartClassNameStringSchema() { - return StringSchema( + StringConfigSpec _dartClassNameStringSchema() { + return StringConfigSpec( schemaDefName: 'publicDartClass', schemaDescription: "A public dart class name.", pattern: r'^[a-zA-Z]+[_a-zA-Z0-9]*$', @@ -799,11 +801,11 @@ class Config { return [ FixedMapEntry( key: strings.include, - valueSchema: _fullMatchOrRegexpList(), + valueConfigSpec: _fullMatchOrRegexpList(), ), FixedMapEntry( key: strings.exclude, - valueSchema: _fullMatchOrRegexpList(), + valueConfigSpec: _fullMatchOrRegexpList(), defaultValue: (node) => [], ), ]; @@ -812,7 +814,7 @@ class Config { ListSchema _fullMatchOrRegexpList() { return ListSchema( schemaDefName: "fullMatchOrRegexpList", - childSchema: StringSchema(), + childSchema: StringConfigSpec(), ); } @@ -820,10 +822,10 @@ class Config { return [ FixedMapEntry( key: strings.rename, - valueSchema: DynamicMapSchema( + valueConfigSpec: DynamicMapConfigSpec( schemaDefName: "rename", - keyValueSchemas: [ - (keyRegexp: ".*", valueSchema: StringSchema()), + keyValueConfigSpecs: [ + (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()), ], ), ), @@ -834,14 +836,14 @@ class Config { return [ FixedMapEntry( key: strings.memberRename, - valueSchema: DynamicMapSchema>( + valueConfigSpec: DynamicMapConfigSpec>( schemaDefName: "memberRename", - keyValueSchemas: [ + keyValueConfigSpecs: [ ( keyRegexp: ".*", - valueSchema: DynamicMapSchema( - keyValueSchemas: [ - (keyRegexp: ".*", valueSchema: StringSchema()) + valueConfigSpec: DynamicMapConfigSpec( + keyValueConfigSpecs: [ + (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()) ], ), ), @@ -851,10 +853,10 @@ class Config { ]; } - FixedMapSchema> _includeExcludeObject() { - return FixedMapSchema>( + FixedMapConfigSpec> _includeExcludeObject() { + return FixedMapConfigSpec>( schemaDefName: "includeExclude", - keys: [ + entries: [ ..._includeExcludeProperties(), ], transform: (node) => extractIncluderFromYaml(node.value), @@ -864,7 +866,7 @@ class Config { FixedMapEntry _dependencyOnlyFixedMapKey() { return FixedMapEntry( key: strings.dependencyOnly, - valueSchema: EnumSchema( + valueConfigSpec: EnumConfigSpec( schemaDefName: "dependencyOnly", allowedValues: { strings.fullCompoundDependencies, @@ -878,16 +880,19 @@ class Config { ); } - DynamicMapSchema _mappedTypeObject() { - return DynamicMapSchema( + DynamicMapConfigSpec _mappedTypeObject() { + return DynamicMapConfigSpec( schemaDefName: "mappedTypes", - keyValueSchemas: [ + keyValueConfigSpecs: [ ( keyRegexp: ".*", - valueSchema: FixedMapSchema(keys: [ - FixedMapEntry(key: strings.lib, valueSchema: StringSchema()), - FixedMapEntry(key: strings.cType, valueSchema: StringSchema()), - FixedMapEntry(key: strings.dartType, valueSchema: StringSchema()), + valueConfigSpec: FixedMapConfigSpec(entries: [ + FixedMapEntry( + key: strings.lib, valueConfigSpec: StringConfigSpec()), + FixedMapEntry( + key: strings.cType, valueConfigSpec: StringConfigSpec()), + FixedMapEntry( + key: strings.dartType, valueConfigSpec: StringConfigSpec()), ]), ) ], @@ -895,11 +900,11 @@ class Config { ); } - DynamicMapSchema _objcInterfaceModuleObject() { - return DynamicMapSchema( + DynamicMapConfigSpec _objcInterfaceModuleObject() { + return DynamicMapConfigSpec( schemaDefName: "objcInterfaceModule", - keyValueSchemas: [ - (keyRegexp: ".*", valueSchema: StringSchema()), + keyValueConfigSpecs: [ + (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()), ], transform: (node) => ObjCModulePrefixer(node.value.cast()), diff --git a/lib/src/config_provider/schema.dart b/lib/src/config_provider/config_spec.dart similarity index 64% rename from lib/src/config_provider/schema.dart rename to lib/src/config_provider/config_spec.dart index cfd4e979..f0cbf3cd 100644 --- a/lib/src/config_provider/schema.dart +++ b/lib/src/config_provider/config_spec.dart @@ -3,8 +3,8 @@ import 'package:yaml/yaml.dart'; final _logger = Logger('ffigen.config_provider.config'); -/// A container object for a Schema Object. -class SchemaNode { +/// A container object for a ConfigSpec Object. +class ConfigSpecNode { /// The path to this node. /// /// E.g - ["path", "to", "arr", "[1]", "item"] @@ -23,7 +23,7 @@ class SchemaNode { /// but default values final Object? rawValue; - SchemaNode({ + ConfigSpecNode({ required this.path, required this.value, Object? rawValue, @@ -31,8 +31,8 @@ class SchemaNode { }) : rawValue = nullRawValue ? null : (rawValue ?? value); /// Copy object with a different value. - SchemaNode withValue(T value, Object? rawValue) { - return SchemaNode( + ConfigSpecNode withValue(T value, Object? rawValue) { + return ConfigSpecNode( path: path, value: value, rawValue: rawValue, @@ -42,11 +42,11 @@ class SchemaNode { /// Transforms this SchemaNode with a nullable [transform] or return itself /// and calls the [result] callback - SchemaNode transformOrThis( - dynamic Function(SchemaNode value)? transform, - void Function(SchemaNode node)? resultCallback, + ConfigSpecNode transformOrThis( + dynamic Function(ConfigSpecNode value)? transform, + void Function(ConfigSpecNode node)? resultCallback, ) { - SchemaNode returnValue = this; + ConfigSpecNode returnValue = this; if (transform != null) { returnValue = this.withValue(transform.call(this), rawValue); } @@ -67,10 +67,10 @@ class SchemaNode { } } -class SchemaExtractionError extends Error { - final SchemaNode? item; +class ConfigSpecExtractionError extends Error { + final ConfigSpecNode? item; final String message; - SchemaExtractionError(this.item, [this.message = "Invalid Schema"]); + ConfigSpecExtractionError(this.item, [this.message = "Invalid Schema"]); @override String toString() { @@ -82,7 +82,7 @@ class SchemaExtractionError extends Error { } /// Base class for all Schemas to extend. -abstract class Schema { +abstract class ConfigSpec { /// Used to generate and refer the reference definition generated in json /// schema. Must be unique for a nested Schema. String? schemaDefName; @@ -91,15 +91,15 @@ abstract class Schema { String? schemaDescription; /// Custom validation hook, called post schema validation if successful. - bool Function(SchemaNode node)? customValidation; + bool Function(ConfigSpecNode node)? customValidation; /// Used to transform the payload to another type before passing to parent /// nodes and [result]. - dynamic Function(SchemaNode node)? transform; + dynamic Function(ConfigSpecNode node)? transform; /// Called when final result is prepared via [_extractNode]. - void Function(SchemaNode node)? result; - Schema({ + void Function(ConfigSpecNode node)? result; + ConfigSpec({ required this.schemaDefName, required this.schemaDescription, required this.customValidation, @@ -107,9 +107,9 @@ abstract class Schema { required this.result, }); - bool _validateNode(SchemaNode o, {bool log = true}); + bool _validateNode(ConfigSpecNode o, {bool log = true}); - SchemaNode _extractNode(SchemaNode o); + ConfigSpecNode _extractNode(ConfigSpecNode o); /// Schema objects should call [_getJsonRefOrSchemaNode] instead to get the /// child json schema. @@ -138,43 +138,44 @@ abstract class Schema { /// Run validation on an object [value]. bool validate(dynamic value) { - return _validateNode(SchemaNode(path: [], value: value)); + return _validateNode(ConfigSpecNode(path: [], value: value)); } /// Extract SchemaNode from [value]. This will call the [transform] for all /// underlying Schemas if valid. /// Should ideally only be called if [validate] returns True. Throws - /// [SchemaExtractionError] if any validation fails. - SchemaNode extract(dynamic value) { - return _extractNode(SchemaNode(path: [], value: value)); + /// [ConfigSpecExtractionError] if any validation fails. + ConfigSpecNode extract(dynamic value) { + return _extractNode(ConfigSpecNode(path: [], value: value)); } } class FixedMapEntry { final String key; - final Schema valueSchema; - final dynamic Function(SchemaNode o)? defaultValue; - void Function(SchemaNode node)? resultOrDefault; + final ConfigSpec valueConfigSpec; + final dynamic Function(ConfigSpecNode o)? defaultValue; + void Function(ConfigSpecNode node)? resultOrDefault; final bool required; FixedMapEntry({ required this.key, - required this.valueSchema, + required this.valueConfigSpec, this.defaultValue, this.resultOrDefault, this.required = false, }); } -/// Schema for a Map which has a fixed set of known keys. -class FixedMapSchema extends Schema> { - final List keys; +/// ConfigSpec for a Map which has a fixed set of known keys. +class FixedMapConfigSpec + extends ConfigSpec> { + final List entries; final Set allKeys; final Set requiredKeys; final bool additionalProperties; - FixedMapSchema({ - required this.keys, + FixedMapConfigSpec({ + required this.entries, super.schemaDefName, super.schemaDescription, super.customValidation, @@ -182,12 +183,12 @@ class FixedMapSchema extends Schema> { super.result, this.additionalProperties = false, }) : requiredKeys = { - for (final kv in keys.where((kv) => kv.required)) kv.key + for (final kv in entries.where((kv) => kv.required)) kv.key }, - allKeys = {for (final kv in keys) kv.key}; + allKeys = {for (final kv in entries) kv.key}; @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!o.checkType(log: log)) { return false; } @@ -205,13 +206,14 @@ class FixedMapSchema extends Schema> { } } - for (final entry in keys) { + for (final entry in entries) { final path = [...o.path, entry.key.toString()]; if (!inputMap.containsKey(entry.key)) { continue; } - final schemaNode = SchemaNode(path: path, value: inputMap[entry.key]); - if (!entry.valueSchema._validateNode(schemaNode, log: log)) { + final configSpecNode = + ConfigSpecNode(path: path, value: inputMap[entry.key]); + if (!entry.valueConfigSpec._validateNode(configSpecNode, log: log)) { result = false; continue; } @@ -231,24 +233,24 @@ class FixedMapSchema extends Schema> { return result; } - dynamic _getAllDefaults(SchemaNode o) { + dynamic _getAllDefaults(ConfigSpecNode o) { final result = {}; - for (final entry in keys) { + for (final entry in entries) { final path = [...o.path, entry.key]; if (entry.defaultValue != null) { - result[entry.key] = - entry.defaultValue!.call(SchemaNode(path: path, value: null)) as CE; - } else if (entry.valueSchema is FixedMapSchema) { - final defaultValue = (entry.valueSchema as FixedMapSchema) - ._getAllDefaults(SchemaNode(path: path, value: null)); + result[entry.key] = entry.defaultValue! + .call(ConfigSpecNode(path: path, value: null)) as CE; + } else if (entry.valueConfigSpec is FixedMapConfigSpec) { + final defaultValue = (entry.valueConfigSpec as FixedMapConfigSpec) + ._getAllDefaults(ConfigSpecNode(path: path, value: null)); if (defaultValue != null) { - result[entry.key] = (entry.valueSchema as FixedMapSchema) - ._getAllDefaults(SchemaNode(path: path, value: null)) as CE; + result[entry.key] = (entry.valueConfigSpec as FixedMapConfigSpec) + ._getAllDefaults(ConfigSpecNode(path: path, value: null)) as CE; } } if (result.containsKey(entry.key) && entry.resultOrDefault != null) { // Call resultOrDefault hook for FixedMapKey. - entry.resultOrDefault!.call(SchemaNode( + entry.resultOrDefault!.call(ConfigSpecNode( path: path, value: result[entry.key], nullRawValue: true)); } } @@ -261,9 +263,9 @@ class FixedMapSchema extends Schema> { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!o.checkType(log: false)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } final inputMap = (o.value as Map); @@ -271,40 +273,42 @@ class FixedMapSchema extends Schema> { for (final requiredKey in requiredKeys) { if (!inputMap.containsKey(requiredKey)) { - throw SchemaExtractionError( - null, "Invalid schema, missing required key - $requiredKey."); + throw ConfigSpecExtractionError( + null, "Invalid config spec, missing required key - $requiredKey."); } } - for (final entry in keys) { + for (final entry in entries) { final path = [...o.path, entry.key.toString()]; if (!inputMap.containsKey(entry.key)) { // No value specified, fill in with default value instead. if (entry.defaultValue != null) { childExtracts[entry.key] = entry.defaultValue! - .call(SchemaNode(path: path, value: null)) as CE; - } else if (entry.valueSchema is FixedMapSchema) { - final defaultValue = (entry.valueSchema as FixedMapSchema) - ._getAllDefaults(SchemaNode(path: path, value: null)); + .call(ConfigSpecNode(path: path, value: null)) as CE; + } else if (entry.valueConfigSpec is FixedMapConfigSpec) { + final defaultValue = (entry.valueConfigSpec as FixedMapConfigSpec) + ._getAllDefaults(ConfigSpecNode(path: path, value: null)); if (defaultValue != null) { - childExtracts[entry.key] = (entry.valueSchema as FixedMapSchema) - ._getAllDefaults(SchemaNode(path: path, value: null)) as CE; + childExtracts[entry.key] = (entry.valueConfigSpec + as FixedMapConfigSpec) + ._getAllDefaults(ConfigSpecNode(path: path, value: null)) as CE; } } } else { // Extract value from node. - final schemaNode = SchemaNode(path: path, value: inputMap[entry.key]); - if (!entry.valueSchema._validateNode(schemaNode, log: false)) { - throw SchemaExtractionError(schemaNode); + final configSpecNode = + ConfigSpecNode(path: path, value: inputMap[entry.key]); + if (!entry.valueConfigSpec._validateNode(configSpecNode, log: false)) { + throw ConfigSpecExtractionError(configSpecNode); } childExtracts[entry.key] = - entry.valueSchema._extractNode(schemaNode).value as CE; + entry.valueConfigSpec._extractNode(configSpecNode).value as CE; } if (childExtracts.containsKey(entry.key) && entry.resultOrDefault != null) { // Call resultOrDefault hook for FixedMapKey. - entry.resultOrDefault!.call(SchemaNode( + entry.resultOrDefault!.call(ConfigSpecNode( path: path, value: childExtracts[entry.key], nullRawValue: true)); } } @@ -319,23 +323,25 @@ class FixedMapSchema extends Schema> { "type": "object", if (!additionalProperties) "additionalProperties": false, if (schemaDescription != null) "description": schemaDescription!, - if (keys.isNotEmpty) + if (entries.isNotEmpty) "properties": { - for (final kv in keys) - kv.key: kv.valueSchema._getJsonRefOrSchemaNode(defs) + for (final kv in entries) + kv.key: kv.valueConfigSpec._getJsonRefOrSchemaNode(defs) }, if (requiredKeys.isNotEmpty) "required": requiredKeys.toList(), }; } } -/// Schema for a Map that can have any number of keys. -class DynamicMapSchema extends Schema> { +/// ConfigSpec for a Map that can have any number of keys. +class DynamicMapConfigSpec + extends ConfigSpec> { /// [keyRegexp] will convert it's input to a String before matching. - final List<({String keyRegexp, Schema valueSchema})> keyValueSchemas; + final List<({String keyRegexp, ConfigSpec valueConfigSpec})> + keyValueConfigSpecs; - DynamicMapSchema({ - required this.keyValueSchemas, + DynamicMapConfigSpec({ + required this.keyValueConfigSpecs, super.schemaDefName, super.schemaDescription, super.customValidation, @@ -344,7 +350,7 @@ class DynamicMapSchema extends Schema> { }); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!o.checkType(log: log)) { return false; } @@ -353,15 +359,15 @@ class DynamicMapSchema extends Schema> { final inputMap = (o.value as Map); for (final MapEntry(key: key, value: value) in inputMap.entries) { - final schemaNode = - SchemaNode(path: [...o.path, key.toString()], value: value); + final configSpecNode = + ConfigSpecNode(path: [...o.path, key.toString()], value: value); var keyValueMatch = false; /// Running first time with no logs. - for (final (keyRegexp: keyRegexp, valueSchema: valueSchema) - in keyValueSchemas) { + for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec) + in keyValueConfigSpecs) { if (RegExp(keyRegexp, dotAll: true).hasMatch(key.toString()) && - valueSchema._validateNode(schemaNode, log: false)) { + valueConfigSpec._validateNode(configSpecNode, log: false)) { keyValueMatch = true; break; } @@ -371,15 +377,15 @@ class DynamicMapSchema extends Schema> { // No schema matched, running again to print logs this time. if (log) { _logger.severe( - "'${schemaNode.pathString}' must match atleast one of the allowed key regex and schema."); - for (final (keyRegexp: keyRegexp, valueSchema: valueSchema) - in keyValueSchemas) { + "'${configSpecNode.pathString}' must match atleast one of the allowed key regex and schema."); + for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec) + in keyValueConfigSpecs) { if (!RegExp(keyRegexp, dotAll: true).hasMatch(key.toString())) { _logger.severe( - "'${schemaNode.pathString}' does not match regex - '$keyRegexp' (Input - $key)"); + "'${configSpecNode.pathString}' does not match regex - '$keyRegexp' (Input - $key)"); continue; } - if (valueSchema._validateNode(schemaNode, log: log)) { + if (valueConfigSpec._validateNode(configSpecNode, log: log)) { continue; } } @@ -394,28 +400,29 @@ class DynamicMapSchema extends Schema> { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!o.checkType(log: false)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } final inputMap = (o.value as Map); final childExtracts = {}; for (final MapEntry(key: key, value: value) in inputMap.entries) { - final schemaNode = - SchemaNode(path: [...o.path, key.toString()], value: value); + final configSpecNode = + ConfigSpecNode(path: [...o.path, key.toString()], value: value); var keyValueMatch = false; - for (final (keyRegexp: keyRegexp, valueSchema: valueSchema) - in keyValueSchemas) { + for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec) + in keyValueConfigSpecs) { if (RegExp(keyRegexp, dotAll: true).hasMatch(key.toString()) && - valueSchema._validateNode(schemaNode, log: false)) { - childExtracts[key] = valueSchema._extractNode(schemaNode).value as CE; + valueConfigSpec._validateNode(configSpecNode, log: false)) { + childExtracts[key] = + valueConfigSpec._extractNode(configSpecNode).value as CE; keyValueMatch = true; break; } } if (!keyValueMatch) { - throw SchemaExtractionError(schemaNode); + throw ConfigSpecExtractionError(configSpecNode); } } @@ -429,19 +436,19 @@ class DynamicMapSchema extends Schema> { return { "type": "object", if (schemaDescription != null) "description": schemaDescription!, - if (keyValueSchemas.isNotEmpty) + if (keyValueConfigSpecs.isNotEmpty) "patternProperties": { - for (final (keyRegexp: keyRegexp, valueSchema: valueSchema) - in keyValueSchemas) - keyRegexp: valueSchema._getJsonRefOrSchemaNode(defs) + for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec) + in keyValueConfigSpecs) + keyRegexp: valueConfigSpec._getJsonRefOrSchemaNode(defs) } }; } } -/// Schema for a List. -class ListSchema extends Schema> { - final Schema childSchema; +/// ConfigSpec for a List. +class ListSchema extends ConfigSpec> { + final ConfigSpec childSchema; ListSchema({ required this.childSchema, @@ -453,15 +460,16 @@ class ListSchema extends Schema> { }); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!o.checkType(log: log)) { return false; } final inputList = (o.value as YamlList).cast(); var result = true; for (final (i, input) in inputList.indexed) { - final schemaNode = SchemaNode(path: [...o.path, "[$i]"], value: input); - if (!childSchema._validateNode(schemaNode, log: log)) { + final configSpecNode = + ConfigSpecNode(path: [...o.path, "[$i]"], value: input); + if (!childSchema._validateNode(configSpecNode, log: log)) { result = false; continue; } @@ -474,19 +482,19 @@ class ListSchema extends Schema> { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!o.checkType(log: false)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } final inputList = (o.value as YamlList).cast(); final childExtracts = []; for (final (i, input) in inputList.indexed) { - final schemaNode = - SchemaNode(path: [...o.path, i.toString()], value: input); - if (!childSchema._validateNode(schemaNode, log: false)) { - throw SchemaExtractionError(schemaNode); + final configSpecNode = + ConfigSpecNode(path: [...o.path, i.toString()], value: input); + if (!childSchema._validateNode(configSpecNode, log: false)) { + throw ConfigSpecExtractionError(configSpecNode); } - childExtracts.add(childSchema._extractNode(schemaNode).value as CE); + childExtracts.add(childSchema._extractNode(configSpecNode).value as CE); } return o .withValue(childExtracts, o.rawValue) @@ -503,12 +511,12 @@ class ListSchema extends Schema> { } } -/// Schema for a String. -class StringSchema extends Schema { +/// ConfigSpec for a String. +class StringConfigSpec extends ConfigSpec { final String? pattern; final RegExp? _regexp; - StringSchema({ + StringConfigSpec({ super.schemaDefName, super.schemaDescription, super.customValidation, @@ -518,7 +526,7 @@ class StringSchema extends Schema { }) : _regexp = pattern == null ? null : RegExp(pattern, dotAll: true); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!o.checkType(log: log)) { return false; } @@ -536,9 +544,9 @@ class StringSchema extends Schema { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!o.checkType(log: false)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } return o .withValue(o.value as String, o.rawValue) @@ -555,9 +563,9 @@ class StringSchema extends Schema { } } -/// Schema for an Int. -class IntSchema extends Schema { - IntSchema({ +/// ConfigSpec for an Int. +class IntConfigSpec extends ConfigSpec { + IntConfigSpec({ super.schemaDefName, super.schemaDescription, super.customValidation, @@ -566,7 +574,7 @@ class IntSchema extends Schema { }); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!o.checkType(log: log)) { return false; } @@ -577,9 +585,9 @@ class IntSchema extends Schema { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!o.checkType(log: false)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } return o .withValue(o.value as int, o.rawValue) @@ -595,10 +603,10 @@ class IntSchema extends Schema { } } -/// Schema for an object where only specific values are allowed. -class EnumSchema extends Schema { +/// ConfigSpec for an object where only specific values are allowed. +class EnumConfigSpec extends ConfigSpec { Set allowedValues; - EnumSchema({ + EnumConfigSpec({ required this.allowedValues, super.schemaDefName, super.schemaDescription, @@ -608,7 +616,7 @@ class EnumSchema extends Schema { }); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!allowedValues.contains(o.value)) { if (log) { _logger.severe( @@ -623,9 +631,9 @@ class EnumSchema extends Schema { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!allowedValues.contains(o.value)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } return o .withValue(o.value as CE, o.rawValue) @@ -641,9 +649,9 @@ class EnumSchema extends Schema { } } -/// Schema for a bool. -class BoolSchema extends Schema { - BoolSchema({ +/// ConfigSpec for a bool. +class BoolConfigSpec extends ConfigSpec { + BoolConfigSpec({ super.schemaDefName, super.schemaDescription, super.customValidation, @@ -652,7 +660,7 @@ class BoolSchema extends Schema { }); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { if (!o.checkType(log: log)) { return false; } @@ -663,9 +671,9 @@ class BoolSchema extends Schema { } @override - SchemaNode _extractNode(SchemaNode o) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { if (!o.checkType(log: false)) { - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } return o .withValue(o.value as bool, o.rawValue) @@ -682,11 +690,11 @@ class BoolSchema extends Schema { } /// Schema which checks if atleast one of the underlying Schema matches. -class OneOfSchema extends Schema { - final List childSchemas; +class OneOfConfigSpec extends ConfigSpec { + final List childConfigSpecs; - OneOfSchema({ - required this.childSchemas, + OneOfConfigSpec({ + required this.childConfigSpecs, super.schemaDefName, super.schemaDescription, super.customValidation, @@ -695,10 +703,10 @@ class OneOfSchema extends Schema { }); @override - bool _validateNode(SchemaNode o, {bool log = true}) { + bool _validateNode(ConfigSpecNode o, {bool log = true}) { // Running first time with no logs. - for (final schema in childSchemas) { - if (schema._validateNode(o, log: false)) { + for (final spec in childConfigSpecs) { + if (spec._validateNode(o, log: false)) { if (customValidation != null) { return customValidation!.call(o); } @@ -709,30 +717,30 @@ class OneOfSchema extends Schema { if (log) { _logger.severe( "'${o.pathString}' must match atleast one of the allowed schema -"); - for (final schema in childSchemas) { - schema._validateNode(o, log: log); + for (final spec in childConfigSpecs) { + spec._validateNode(o, log: log); } } return false; } @override - SchemaNode _extractNode(SchemaNode o) { - for (final schema in childSchemas) { - if (schema._validateNode(o, log: false)) { + ConfigSpecNode _extractNode(ConfigSpecNode o) { + for (final spec in childConfigSpecs) { + if (spec._validateNode(o, log: false)) { return o - .withValue(schema._extractNode(o).value as E, o.rawValue) + .withValue(spec._extractNode(o).value as E, o.rawValue) .transformOrThis(transform, result); } } - throw SchemaExtractionError(o); + throw ConfigSpecExtractionError(o); } @override Map _generateJsonSchemaNode(Map defs) { return { if (schemaDescription != null) "description": schemaDescription!, - r"$oneOf": childSchemas + r"$oneOf": childConfigSpecs .map((child) => child._getJsonRefOrSchemaNode(defs)) .toList(), };