rsynko_manager/options.rs
1use alux_ext::ext;
2use alux_sdk::trait_algebra;
3use rsynko_media::{FormatPredicateAlg, FormatPredicateExt, FormatSelectionAlg};
4
5/// Specifies what one request states about the media it selects.
6pub trait RequestOptionsAlg {
7 /// Observes what performs the request.
8 fn performer(&self) -> Performer;
9
10 /// Observes the stream roles the request prefers, and that it chooses no media when it
11 /// transfers something a media role says nothing about.
12 fn media_streams(&self) -> Option<MediaStreams>;
13
14 /// Observes the one choice the request fixes, when it fixes one.
15 ///
16 /// What the choices are depends on what the request transfers: one representation of a media
17 /// item, or one way of transferring a folder. Either way, exactly one may be fixed.
18 fn chosen_choice(&self) -> Option<&str>;
19
20 /// Observes every choice the request offers, in the order it offers them.
21 ///
22 /// A media item offers what extraction discovered, and its stream roles state which of them
23 /// is *preferred* when none is fixed; they never hide one the source states. A folder offers every way it may be transferred.
24 fn selectable_choices(&self) -> impl Iterator<Item = &str>;
25
26 /// Observes what one offered choice states about itself, when it states anything.
27 ///
28 /// A choice a reader would not recognize by name says what it does; one described by what it
29 /// carries is read through that description instead.
30 fn choice_summary(&self, choice: &str) -> Option<&str>;
31}
32
33/// Defines the first-order observation stream of format discovery.
34///
35/// An observation is a method, so the reified stream is generated from this vocabulary rather than
36/// written out. An interpreter states what each observation *means* and never restates the shape.
37#[trait_algebra(derive(Clone, Debug, PartialEq, Eq))]
38pub trait FormatDiscovery {
39 /// Represents one described selectable format.
40 type Format;
41
42 /// Denotes that an interpreter started source inspection.
43 fn started(&self);
44
45 /// Supplies the described formats in extractor preference order.
46 fn available(&self, formats: Vec<Self::Format>);
47
48 /// Denotes source inspection failure.
49 fn failed(&self, message: String);
50}
51
52/// Derives the media one request selects from the choices it states.
53#[ext(name = RequestSelectionExt)]
54pub impl<This> This
55where
56 This: FormatPredicateAlg + FormatSelectionAlg,
57{
58 /// Defines the selection one request's own choices state.
59 fn request_selection(&self, options: &impl RequestOptionsAlg) -> This::Selection {
60 let predicate = match options.chosen_choice() {
61 // A fixed identity names exactly one format, so the stream roles add nothing to it.
62 Some(choice) => self.format_id(choice),
63 // A request choosing no media role is not one this program retrieves, so it asks for
64 // the whole thing and lets selection refuse it.
65 None => self.stream_role_format(options.media_streams().unwrap_or(MediaStreams::AudioVideo)),
66 };
67 self.best_format(predicate)
68 }
69}
70
71/// Derives the format predicate one set of stream roles requires.
72#[ext(name = MediaStreamsExt)]
73pub impl<This> This
74where
75 This: FormatPredicateAlg,
76{
77 /// Defines the predicate accepting exactly the formats those roles require.
78 fn stream_role_format(&self, streams: MediaStreams) -> This::Predicate {
79 match streams {
80 MediaStreams::AudioVideo => self.progressive_format(),
81 MediaStreams::Audio => self.audio_only_format(),
82 MediaStreams::Video => self.video_only_format(),
83 }
84 }
85}
86
87/// Denotes what performs one request.
88///
89/// A request is either run by naming a program and reading what it writes, or retrieved by this
90/// program itself from wherever the source that claimed it keeps what it names. How many files
91/// come to rest, and whether they land in a folder, follows from what the request chose — not
92/// from which of these performs it.
93#[derive(Clone, Copy, Debug, PartialEq, Eq)]
94pub enum Performer {
95 /// Denotes a request performed by naming a program and reading what it writes.
96 Program,
97 /// Denotes a request this program retrieves for itself.
98 Retrieval,
99}
100
101/// Selects the stream roles a request prefers when it fixes no format identity.
102#[derive(Clone, Copy, Debug, PartialEq, Eq)]
103pub enum MediaStreams {
104 /// Selects a progressive format containing both audio and video.
105 AudioVideo,
106 /// Selects a format containing audio and no video.
107 Audio,
108 /// Selects a format containing video and no audio.
109 Video,
110}
111
112impl MediaStreams {
113 /// States the roles a request may prefer, in the order they are offered.
114 pub const OFFERED: [Self; 3] = [Self::AudioVideo, Self::Video, Self::Audio];
115}