Skip to main content

klib/core/
base.rs

1//! Base types and traits.
2
3// Helpers.
4
5#[cfg(feature = "audio")]
6use rodio::{OutputStream, Sink};
7
8/// Global result type.
9pub type Res<T> = anyhow::Result<T>;
10
11/// Global error type.
12pub type Err = anyhow::Error;
13
14/// Global void type.
15pub type Void = Res<()>;
16// Traits.
17
18/// A trait for types that have a static name.
19pub trait HasStaticName {
20    /// Returns the static name of the type.
21    fn static_name(&self) -> &'static str;
22}
23
24/// A trait for types that have a computed name.
25pub trait HasName {
26    /// Returns the computed name of the type.
27    fn name(&self) -> String;
28
29    /// Returns the computed name of the type in ASCII.
30    fn name_ascii(&self) -> String {
31        self.name().replace('♯', "#").replace('♭', "b").replace('𝄪', "##").replace('𝄫', "bb").replace("°", "dim")
32    }
33}
34
35/// A trait for types that have a computed name.
36pub trait HasPreciseName {
37    /// Returns the computed name of the type.
38    fn precise_name(&self) -> String;
39}
40
41/// A trait for types that have a description.
42pub trait HasDescription {
43    /// Returns the description of the type.
44    fn description(&self) -> &'static str;
45}
46
47/// A trait for types that can be parsed from a string.
48pub trait Parsable {
49    /// Parses the type from a string.
50    fn parse(symbol: &str) -> Res<Self>
51    where
52        Self: Sized;
53}
54
55/// A struct for holding the types for a [`Playable`].
56#[cfg(feature = "audio")]
57pub struct PlaybackHandle {
58    _stream: OutputStream,
59    _sinks: Vec<Sink>,
60}
61
62#[cfg(feature = "audio")]
63impl PlaybackHandle {
64    /// Creates a new [`PlayableResult`].
65    pub fn new(stream_handle: OutputStream, sinks: Vec<Sink>) -> Self {
66        Self { _stream: stream_handle, _sinks: sinks }
67    }
68}
69
70/// A trait for types that can be "played" via the system's audio output.
71/// ```rust, no_run
72/// use std::time::Duration;
73///
74/// use klib::core::base::Playable;
75/// use klib::core::{named_pitch::NamedPitch, note::Note, octave::Octave};
76///
77/// let handle = Note::new(NamedPitch::A, Octave::Four).play(
78///     Duration::ZERO,
79///     Duration::from_secs(1),
80///     Duration::ZERO,
81/// );
82/// std::thread::sleep(Duration::from_secs(1));
83/// ```
84#[cfg(feature = "audio")]
85pub trait Playable {
86    /// Plays the [`Playable`].
87    #[must_use = "Dropping the PlayableResult will stop the playback."]
88    fn play(&self, delay: std::time::Duration, length: std::time::Duration, fade_in: std::time::Duration) -> Res<PlaybackHandle>;
89}