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