diff --git a/lib/src/state/state.dart b/lib/src/state/state.dart index 6a193ca..a350a6f 100644 --- a/lib/src/state/state.dart +++ b/lib/src/state/state.dart @@ -35,7 +35,7 @@ abstract class OctopusState extends _OctopusTree { /// Current state representation as a [Uri] /// e.g. /shop/category?id=1/category?id=12/product?id=123 - Uri get uri => StateUtil.encodeLocation(this); + Uri get uri; /// Current state representation as a location string. String get location; @@ -127,6 +127,9 @@ class OctopusState$Mutable extends OctopusState @override bool get isMutable => true; + @override + Uri get uri => StateUtil.encodeLocation(this); + @override String get location => uri.toString(); @@ -179,6 +182,9 @@ class OctopusState$Immutable extends OctopusState @override bool get isMutable => false; + @override + late final Uri uri = StateUtil.encodeLocation(this); + @override late final String location = uri.toString(); diff --git a/lib/src/state/state_util.dart b/lib/src/state/state_util.dart index 5cd8942..5a98e68 100644 --- a/lib/src/state/state_util.dart +++ b/lib/src/state/state_util.dart @@ -79,6 +79,49 @@ abstract final class StateUtil { ); } + /* @internal + static Future encodeLocationAsync(OctopusState state) async { + final segments = []; + final stopwatch = Stopwatch()..start(); + try { + Future encodeNode(OctopusNode node, int depth) async { + if (stopwatch.elapsedMilliseconds > 8) { + await Future.delayed(Duration.zero); + stopwatch.reset(); + } + final prefix = '.' * depth; + final String name; + if (node.arguments.isEmpty) { + name = node.name; + } else { + final args = (node.arguments.entries.toList(growable: false) + ..sort((a, b) => a.key.compareTo(b.key))) + .map((e) => '${Uri.encodeComponent(e.key)}' + '=' + '${Uri.encodeComponent(e.value)}') + .join('&'); + name = args.isEmpty ? node.name : '${node.name}~$args'; + } + + segments.add('$prefix$name'); + + for (final child in node.children) { + await encodeNode(child, depth + 1); + } + } + + for (final node in state.children) { + await encodeNode(node, 0); + } + } finally { + stopwatch.stop(); + } + return Uri( + pathSegments: segments, + queryParameters: state.arguments.isEmpty ? null : state.arguments, + ); + } */ + /// Convert location string to tree components. /// {@nodoc} @internal