1use std::{path::Path, sync::Arc};
2
3use bytes::Bytes;
4use rodio::{Sample, Sink, Source, SpatialSink};
5
6#[cfg(feature = "playback")]
7use crate::channel_volume::ChannelVolumeSink;
8use crate::{cache::download, error::Result};
9
10pub type BoxSource = Box<dyn Source<Item = Sample> + Send>;
11
12#[derive(Clone)]
13pub struct Chatsound {
14 pub repo: String,
16 pub repo_path: String,
18 pub sound_path: String,
20}
21
22impl Chatsound {
23 #[must_use]
24 pub fn get_url(&self) -> String {
25 format!(
26 "https://raw.githubusercontent.com/{}/HEAD/{}/{}",
27 self.repo, self.repo_path, self.sound_path
28 )
29 }
30
31 #[must_use]
32 pub fn get_web_url(&self) -> String {
33 format!(
34 "https://github.com/{}/blob/HEAD/{}/{}",
35 self.repo, self.repo_path, self.sound_path
36 )
37 }
38
39 #[cfg(feature = "fs")]
40 pub async fn load(&self, cache_path: &Path) -> Result<Bytes> {
41 let url = self.get_url();
42 download(&url, cache_path, true).await
43 }
44
45 #[cfg(feature = "memory")]
46 pub async fn load(&self, fs_memory: crate::FsMemory) -> Result<Bytes> {
47 let url = self.get_url();
48 download(&url, fs_memory, true).await
49 }
50}
51
52#[cfg(feature = "playback")]
53pub trait ChatsoundsSink {
54 fn sleep_until_end(&self);
55 fn stop(&self);
56 fn set_volume(&self, volume: f32);
57}
58
59#[cfg(feature = "playback")]
60impl ChatsoundsSink for Arc<Sink> {
61 fn sleep_until_end(&self) {
62 Sink::sleep_until_end(self);
63 }
64
65 fn stop(&self) {
66 Sink::stop(self);
67 }
68
69 fn set_volume(&self, volume: f32) {
70 Sink::set_volume(self, volume);
71 }
72}
73
74#[cfg(feature = "playback")]
75impl ChatsoundsSink for Arc<SpatialSink> {
76 fn sleep_until_end(&self) {
77 SpatialSink::sleep_until_end(self);
78 }
79
80 fn stop(&self) {
81 SpatialSink::stop(self);
82 }
83
84 fn set_volume(&self, volume: f32) {
85 SpatialSink::set_volume(self, volume);
86 }
87}
88
89#[cfg(feature = "playback")]
90impl ChatsoundsSink for Arc<ChannelVolumeSink> {
91 fn sleep_until_end(&self) {
92 Sink::sleep_until_end(&self.sink);
93 }
94
95 fn stop(&self) {
96 Sink::stop(&self.sink);
97 }
98
99 fn set_volume(&self, volume: f32) {
100 Sink::set_volume(&self.sink, volume);
101 }
102}