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}