Skip to content

Commit

Permalink
refactor: clean up & optimize code
Browse files Browse the repository at this point in the history
> simplify pair definition using Dart records
> apply changes to `NodeData` object
>  add method to return shortest key path for recursive rename
>  update replacer to use shortest key path
  • Loading branch information
kekavc24 committed Dec 3, 2023
1 parent 5c21474 commit 194b9c0
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 124 deletions.
14 changes: 10 additions & 4 deletions lib/src/core/yaml_transformers/data/matched_node_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,19 @@ class MatchedNodeData {
return (indexMap: indexMap, keys: keys);
}

/// Get path of keys upto the last renameable key
String getPathToLastKey() {
/// Get list of keys upto the last renameable key
Iterable<Key> getUptoLastRenameable() {
// Get max
final keyRecord = getMatchedKeysIndex();
final lastIndex = keyRecord.indexMap.values.max; // Get max
final lastIndex = keyRecord.indexMap.values.max;

// Keys to be taken, include last index plus one
return keyRecord.keys.take(lastIndex + 1).join('/');
return keyRecord.keys.take(lastIndex + 1);
}

/// Get path of keys upto the last renameable key
String getPathToLastKey() {
return getUptoLastRenameable().join('/');
}

@override
Expand Down
62 changes: 27 additions & 35 deletions lib/src/core/yaml_transformers/data/node_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,34 @@ part of '../yaml_transformer.dart';
class NodeData {
const NodeData._(this.precedingKeys, this.key, this.value);

/// Create with default constructor
factory NodeData.skeleton({
required List<Key> precedingKeys,
required Key key,
required Value value,
}) {
return NodeData._(precedingKeys, key, value);
}

/// Create using List<String> path and key
factory NodeData.stringSkeleton({
required List<String> path,
required String key,
required String value,
}) {
return NodeData.skeleton(
precedingKeys: path.map((e) => createKey(value: e)).toList(),
key: createKey(value: key),
value: createValue(value: value),
);
}

/// Create from the root anchor key
factory NodeData.fromRoot({required String key, required dynamic value}) {
return NodeData._(
const [],
_createPairType<Key>(isKey: true, value: key),
_createPairType<Value>(isKey: false, value: value),
createKey(value: key),
createValue(value: value),
);
}

Expand All @@ -30,13 +52,8 @@ class NodeData {
}) {
return NodeData._(
[...parent.precedingKeys, parent.key],
_createPairType<Key>(
isKey: true,
value: current.key,
level: indices.isEmpty ? Level.normal : Level.nested,
indices: indices,
),
_createPairType<Value>(isKey: false, value: current.value),
createKey(value: current.key as String?, indices: indices),
createValue(value: current.value),
);
}

Expand All @@ -56,12 +73,7 @@ class NodeData {
return NodeData._(
[...parent.precedingKeys],
parent.key,
_createPairType<Value>(
isKey: false,
value: terminalValue,
level: indices.isEmpty ? Level.normal : Level.nested,
indices: indices,
),
createValue(value: terminalValue, indices: indices),
);
}

Expand Down Expand Up @@ -139,23 +151,3 @@ class NodeData {
precedingKeys.isNotEmpty &&
precedingKeys.any((element) => element.isNested());
}

/// Creates a specialized PairType
T _createPairType<T extends PairType>({
required bool isKey,
required dynamic value,
Level? level,
List<int>? indices,
}) {
return isKey
? Key(
value: value as String,
level: level ?? Level.normal,
indices: indices ?? [],
) as T
: Value(
value: isTerminal(value) ? value.toString() : value,
level: level ?? Level.normal,
indices: indices ?? [],
) as T;
}
24 changes: 0 additions & 24 deletions lib/src/core/yaml_transformers/data/pair_definition/key.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,32 +1,59 @@
import 'package:magical_version_bump/src/utils/typedefs/typedefs.dart';
import 'package:meta/meta.dart';

part 'key.dart';
part 'value.dart';

/// Level of a key/value in a map
enum Level {
/// Direct value of a key
normal,

/// Nested in a list
nested
/// Custom key/value definition
///
/// `value` - indicates the actual value
/// `indices` - indicates the list of indices when nested in 1 or more lists
typedef PairType<T> = ({T? value, List<int> indices});

/// A key in a custom key/value definition
///
/// See [PairType]
typedef Key = PairType<String>;

/// A value in a custom key/value definition
///
/// See [PairType]
typedef Value = PairType<dynamic>;

T _pairType<T>({
required dynamic value,
required List<int> indices,
}) {
return (value: value, indices: indices) as T;
}

/// Forms the base class for a key/value in a map
abstract base class PairType {
PairType({required this.level, required this.indices});

/// Level in based on parent key
final Level level;

/// List of indices in order of nested level
final List<int> indices;
/// Create key
Key createKey({String? value, List<int>? indices}) => _pairType(
value: value,
indices: indices ?? [],
);

/// Creates a list of keys
List<Key> createListOfKeys({
required List<String> keys,
required Map<String, List<int>> linkedIndices,
}) {
return keys
.map((e) => createKey(value: e, indices: linkedIndices[e]))
.toList();
}

/// Checks whether this key is nested
bool isNested() => level == Level.nested;
/// Create value
Value createValue({required dynamic value, List<int>? indices}) => _pairType(
value: value,
indices: indices ?? [],
);

/// Creates a list of keys
List<Value> createListOfValues({
required List<String> keys,
required Map<String, List<int>> linkedIndices,
}) {
return keys
.map((e) => createValue(value: e, indices: linkedIndices[e]))
.toList();
}

/// Checks whether they are on the same level
bool _isSameLevel(PairType other) =>
level == other.level && collectionsMatch(indices, other.indices);
extension PairTypeExtension<T> on PairType<T> {
/// Checks if nested in a list
bool isNested() => this.indices.isNotEmpty;
}
32 changes: 0 additions & 32 deletions lib/src/core/yaml_transformers/data/pair_definition/value.dart

This file was deleted.

10 changes: 8 additions & 2 deletions lib/src/core/yaml_transformers/replacers/key_replacer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,16 @@ class MagicalRenamer extends Replacer {
checkForKey: true,
);

// Get path to last renameable key inclusive of last key
final pathToLastKey = [...matchedNodeData.getUptoLastRenameable()];

// Remove last which will act as our pseudo target
final target = pathToLastKey.removeLast();

final updatedMap = modifiable.updateIndexedMap(
null,
target: matchedNodeData.nodeData.key,
path: matchedNodeData.nodeData.precedingKeys,
target: target,
path: pathToLastKey,
keyAndReplacement: replacementPair,
value: null,
);
Expand Down

0 comments on commit 194b9c0

Please sign in to comment.