diff --git a/src/arclet/alconna/sistana/model/fragment.py b/src/arclet/alconna/sistana/model/fragment.py index 3142fa15..0f658948 100644 --- a/src/arclet/alconna/sistana/model/fragment.py +++ b/src/arclet/alconna/sistana/model/fragment.py @@ -15,6 +15,7 @@ class _Fragment: name: str variadic: bool = False default: Some[Any] = None + export: bool = False separators: str | None = None hybrid_separators: bool = True diff --git a/src/arclet/alconna/sistana/model/mix.py b/src/arclet/alconna/sistana/model/mix.py index 17a567f7..2b0666f0 100644 --- a/src/arclet/alconna/sistana/model/mix.py +++ b/src/arclet/alconna/sistana/model/mix.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Any, Iterable from ..err import CaptureRejected, ReceivePanic, TransformPanic, ValidateRejected -from ..some import Value +from ..some import Some, Value from .fragment import _Fragment, assert_fragments_order if TYPE_CHECKING: @@ -234,3 +234,23 @@ def complete_track(self, name: str): def complete_all(self): for track in self.tracks.values(): track.complete() + + def export_track(self, name: str) -> dict[str, Some[Any]]: + track = self.tracks[name] + result = {} + for frag in self.preset.tracks[name].fragments: + if not frag.export: + continue + + if frag.name in track.assignes: + result[frag.name] = Value(track.assignes[frag.name]) + else: + result[frag.name] = None + + if track.header is not None and track.header.export: + if track.header.name in track.assignes: + result[track.header.name] = Value(track.assignes[track.header.name]) + else: + result[track.header.name] = None + + return result diff --git a/src/arclet/alconna/sistana/model/snapshot.py b/src/arclet/alconna/sistana/model/snapshot.py index 49d727c0..c9821863 100644 --- a/src/arclet/alconna/sistana/model/snapshot.py +++ b/src/arclet/alconna/sistana/model/snapshot.py @@ -1,14 +1,14 @@ from __future__ import annotations from collections import defaultdict -from typing import TYPE_CHECKING, Generic, TypeVar +from typing import TYPE_CHECKING, Any, Generic, TypeVar from ..some import Some, Value if TYPE_CHECKING: - from .pattern import SubcommandPattern, OptionPattern - from .pointer import Pointer from .mix import Mix, Track + from .pattern import OptionPattern, SubcommandPattern + from .pointer import Pointer T = TypeVar("T") @@ -109,3 +109,26 @@ def determined(self): def determine(self, endpoint: Pointer): self.endpoint = Value(endpoint) + + def _export(self): + result: dict[Pointer, dict[str, Some[Any]]] = {} + + for traverse in self.traverses: + mix = traverse.mix + result[traverse.ref] = mix.export_track(traverse.trigger) + for option in traverse.subcommand.options.values(): + ref = traverse.ref.option(option.keyword) + + if ref in result: + continue + + result[ref] = mix.export_track(option.keyword) + + return result + + def export(self): + a = iter(self._export().values()) + r = next(a).copy() + for b in a: + r.update(b) + return r