ayan_player_cli/
config.rs

1use crate::player::{get_player_from_str, PlayerType};
2use dirs;
3use serde::{Deserialize, Serialize};
4use std::{self, env, fs, path::PathBuf};
5
6#[derive(Debug)]
7pub enum ConfigError {
8    VolumeTypeMismatch,
9    SpeedTypeMismatch,
10    PlayerTypeMismatch,
11    FilterTypeMismatch,
12    HelpAsked,
13}
14
15#[derive(Debug, Serialize, Deserialize)]
16pub struct Configs {
17    volume_lvl: Option<f32>,
18    speed: Option<f32>,
19    pub player: PlayerType,
20    pub filter: Option<String>,
21}
22
23impl Configs {
24    pub fn get_volume(&self) -> f32 {
25        self.volume_lvl.unwrap_or(100.0)
26    }
27
28    pub fn get_speed(&self) -> f32 {
29        self.speed.unwrap_or(1.0)
30    }
31
32
33    pub fn get_config_from_args(mut args: env::Args) -> Result<Self, ConfigError> {
34        args.next();
35
36        let mut volume: Option<f32> = None;
37        let mut speed: Option<f32> = None;
38        let mut player: Option<PlayerType> = None;
39        let mut filter: Option<String> = None;
40        let mut set_as_default = false;
41
42        let arg_parsed: Option<ConfigError> = loop {
43            let a = args.next();
44            match a {
45                Some(arg) => {
46                    if arg == "-s" {
47                        let speed_arg = args.next();
48                        let speed_arg = match speed_arg {
49                            Some(v) => v,
50                            None => break Some(ConfigError::SpeedTypeMismatch),
51                        };
52                        let b = speed_arg.parse::<f32>();
53                        println!("{:?}", b);
54                        match b {
55                            Ok(val) => speed = Some(val),
56                            Err(_) => break Some(ConfigError::SpeedTypeMismatch),
57                        }
58                    } else if arg == "-v" {
59                        let vol_arg = args.next();
60                        let vol_arg = match vol_arg {
61                            Some(v) => v,
62                            None => break Some(ConfigError::VolumeTypeMismatch),
63                        };
64                        let b = vol_arg.parse::<f32>();
65                        println!("{:?}", b);
66                        match b {
67                            Ok(val) => volume = Some(val),
68                            Err(_) => break Some(ConfigError::VolumeTypeMismatch),
69                        }
70                    } else if arg == "--h" || arg == "-help" {
71                        return Err(ConfigError::HelpAsked);
72                    } else if arg == "-player" {
73                        let player_arg = args.next();
74                        let player_arg = match player_arg {
75                            Some(v) => v,
76                            None => break Some(ConfigError::PlayerTypeMismatch),
77                        };
78                        player = Some(get_player_from_str(&player_arg));
79                    } else if arg == "-f" {
80                        let filter_arg = args.next();
81                        filter = match filter_arg {
82                            Some(v) => Some(v),
83                            None => break Some(ConfigError::FilterTypeMismatch),
84                        };
85                    } else if arg == "--set-default" {
86                        set_as_default = true;
87                    }
88                }
89                None => break None,
90            }
91        };
92
93        match arg_parsed {
94            Some(er) => return Err(er),
95            None => {}
96        }
97
98        let config = match Self::get_default_config() {
99            Ok(default) => Configs {
100                volume_lvl: Some(volume.unwrap_or_else(|| default.get_volume())),
101                speed: Some(speed.unwrap_or_else(|| default.get_speed())),
102                player: player.unwrap_or_else(|| default.player),
103                filter 
104            },
105            Err(e) => {
106                match e.kind() {
107                    std::io::ErrorKind::NotFound => (),
108                    _ => {
109                        // TODO: Do something on not able to open read default config
110                    }
111                };
112                Configs {
113                    volume_lvl: volume,
114                    speed,
115                    player: player.unwrap_or_else(|| PlayerType::Other),
116                    filter 
117                }
118            }
119        };
120
121        if set_as_default {
122            _ = config.set_default_config();
123        }
124
125        Ok(config)
126    }
127
128    fn set_default_config(&self) -> Result<(), std::io::Error> {
129        let mut user_config_dir = dirs::config_dir()
130            .unwrap_or_else(|| PathBuf::from("~/.config"))
131            .join("player-cli");
132
133        if !user_config_dir.exists() {
134            fs::create_dir(&user_config_dir)?;
135        }
136
137        user_config_dir = user_config_dir.join("config.json");
138        let json = serde_json::to_string(self)?;
139        fs::write(user_config_dir, json)?;
140        Ok(())
141    }
142
143    fn get_default_config() -> Result<Self, std::io::Error> {
144        let user_config_file_path = dirs::config_dir()
145            .unwrap_or_else(|| PathBuf::from("~/.config"))
146            .join("player-cli")
147            .join("config.json");
148
149        let json_string = fs::read_to_string(user_config_file_path)?;
150        let a: Configs = serde_json::from_str(&json_string)?;
151        Ok(a)
152    }
153}