rsynko-ui
rsynko-ui defines what a transfer manager looks like without saying what draws it. It owns the key map, the menu a page offers, the composition of every page, the words a reader reads, the weight each of them carries, and the resolution a progress bar states a share at. rsynko-manager owns what the application means; this specification owns how that meaning is presented.
A renderer supplies mechanism only: colors, widgets, borders, layout, cursors, and input decoding. Two renderers that disagree about every one of those still agree about everything here.
Specification surface
Input is a value, not a callback:
- [
Key] names one key independently of the mechanism reporting it; - [
Keystroke] adds the modifiers that change what a key denotes, and [EXIT_KEYSTROKE] names the one chord every page binds, which is what leaves the application; - [
KeyBinding] states the keys reaching one intention and the menu action gating it.
KeyBindingExt derives the map from the current page: page_bindings states every binding a page holds, keystroke_meaning states what one keystroke denotes there, and action_keys states which keys reach one action. KeyInputExt::apply_keystroke applies what a keystroke denotes and refuses it when the gating action has no meaning, so a disabled menu entry and a pressed key refuse the same intention for the same reason.
use ;
assert_eq!;
assert_eq!;
assert_eq!;
[MenuItem] states one offered entry: the action, the keys reaching it, the verb it performs here, and whether it currently means anything. MenuPresentationExt::menu_items derives the whole menu from the page's bindings and the manager's own availability, so a menu never states a key the page does not bind.
use ;
use ;
let item = MenuItem ;
assert_eq!;
[Emphasis] is the weight a run of text carries — heading, selected, muted, running, failed — never a color. PhaseVocabularyExt, ControlVocabularyExt, StreamVocabularyExt, and SpaceVocabularyExt name the manager's own values the way a reader reads them, and [bytes_label], [duration_label], and [elided] state quantities in the width a column has.
use TransferPhase;
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
[Gauge] states a completed share at an eighth of a cell, the finest resolution a terminal column has. The unfilled remainder is counted, not drawn, so a renderer states the track however its medium can.
use Gauge;
let gauge = of;
assert_eq!;
assert_eq!;
assert_eq!;
[FormatDescriptionAlg] states what distinguishes one selectable format from its alternatives, and FormatLabelExt::format_label derives the aligned line a chooser compares them by. [FormatChoiceViewAlg] states what discovery has said about one request's formats, as [DiscoveryState].
Screens
[ScreenSyntax] is the presentation vocabulary itself: runs of text carrying an emphasis, lines, rows, bodies that hold rows or a message or a draft or a record, and one screen composed from a header, a body, a status, and a footer. ManagerScreenExt::screen composes every manager page out of that vocabulary alone. Nothing in the composition names a widget, a border, a color, or a terminal.
[ScreenSyntax::screen_text] closes the loop: every renderer can say what its own screen reads as, which is what lets one presentation law run against the renderer that will actually draw it rather than against a stand-in.
Laws
GaugeLaws::gauge_laws checks that a gauge occupies its width whatever share it states, never states a share before it is reached, and states nothing at zero and everything at one hundred.
KeyBindingLaws::key_binding_laws checks that no page binds one keystroke twice, that every bound keystroke denotes its binding, that exit is bound everywhere and no other modified keystroke denotes anything, that typed scalars insert exactly where a draft is held, and that a refused key leaves the manager as it was.
MenuPresentationLaws::menu_presentation_laws checks that every entry states its keys in brackets, that every stated key denotes that entry's action, that every page offers exit last, and that an entry is stated as unavailable exactly when its action has no meaning.
ScreenLaws::screen_laws checks that every page names the path that reached it, states every menu entry it offers, names the key that fills an empty collection, states every offered details control exactly once, and states every note a record holds. A scenario reads screens back through the renderer [ScreenLawFixture] supplies, so a renderer is checked, not simulated.
Composing a screen is an extension, and its bounds are the vocabulary. Nothing here names a color, a widget, or a terminal:
use ext;
use ;
What a chooser reads about one format is derived the same way, from what the format states about itself:
use ext;
use MediaStreams;
use ;