ayan_player_cli/
config.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use colored::Colorize;
use dirs;
use serde::{Deserialize, Serialize};
use std::{self, borrow::Borrow, default, env, fs, path::PathBuf};

use crate::player::{get_player_from_str, PlayerType};

#[derive(Debug)]
pub enum ConfigError {
    VolumeTypeMismatch,
    SpeedTypeMismatch,
    PlayerTypeMismatch,
    HelpAsked,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Configs {
    volume_lvl: Option<f32>,
    speed: Option<f32>,
    pub player: PlayerType,
}

impl Configs {
    pub fn get_volume(&self) -> f32 {
        self.volume_lvl.unwrap_or(100.0)
    }

    pub fn get_speed(&self) -> f32 {
        self.speed.unwrap_or(1.0)
    }

    pub fn get_config_from_args(mut args: env::Args) -> Result<Self, ConfigError> {
        args.next();

        let mut volume: Option<f32> = None;
        let mut speed: Option<f32> = None;
        let mut player: Option<PlayerType> = None;
        let mut set_as_default = false;

        let arg_parsed: Option<ConfigError> = loop {
            let a = args.next();
            match a {
                Some(arg) => {
                    if arg == "-s" {
                        let speed_arg = args.next();
                        let speed_arg = match speed_arg {
                            Some(v) => v,
                            None => break Some(ConfigError::SpeedTypeMismatch),
                        };
                        let b = speed_arg.parse::<f32>();
                        println!("{:?}", b);
                        match b {
                            Ok(val) => speed = Some(val),
                            Err(_) => break Some(ConfigError::SpeedTypeMismatch),
                        }
                    } else if arg == "-v" {
                        let vol_arg = args.next();
                        let vol_arg = match vol_arg {
                            Some(v) => v,
                            None => break Some(ConfigError::VolumeTypeMismatch),
                        };
                        let b = vol_arg.parse::<f32>();
                        println!("{:?}", b);
                        match b {
                            Ok(val) => volume = Some(val),
                            Err(_) => break Some(ConfigError::VolumeTypeMismatch),
                        }
                    } else if arg == "--h" || arg == "-help" {
                        return Err(ConfigError::HelpAsked);
                    } else if arg == "-player" {
                        let player_arg = args.next();
                        let player_arg = match player_arg {
                            Some(v) => v,
                            None => break Some(ConfigError::PlayerTypeMismatch),
                        };
                        player = Some(get_player_from_str(&player_arg));
                    } else if arg == "-set-default" {
                        set_as_default = true;
                    }
                }
                None => break None,
            }
        };

        match arg_parsed {
            Some(er) => return Err(er),
            None => {}
        }

        let config = match Self::get_default_config() {
            Ok(default) => Configs {
                volume_lvl: Some(volume.unwrap_or_else(|| default.get_volume())),
                speed: Some(speed.unwrap_or_else(|| default.get_speed())),
                player: player.unwrap_or_else(|| default.player),
            },
            Err(e) => {
                match e.kind() {
                    std::io::ErrorKind::NotFound => (),
                    _ => {
                        // TODO: Do something on not able to open read default config
                    }
                };
                Configs {
                    volume_lvl: volume,
                    speed,
                    player: player.unwrap_or_else(|| PlayerType::Other),
                }
            }
        };

        if set_as_default {
            _ = config.set_default_config();
        }

        Ok(config)
    }

    fn set_default_config(&self) -> Result<(), std::io::Error> {
        let mut user_config_dir = dirs::config_dir()
            .unwrap_or_else(|| PathBuf::from("~/.config"))
            .join("player-cli");

        if !user_config_dir.exists() {
            fs::create_dir(&user_config_dir)?;
        }

        user_config_dir = user_config_dir.join("config.json");
        let json = serde_json::to_string(self)?;
        fs::write(user_config_dir, json)?;
        Ok(())
    }

    fn get_default_config() -> Result<Self, std::io::Error> {
        let user_config_file_path = dirs::config_dir()
            .unwrap_or_else(|| PathBuf::from("~/.config"))
            .join("player-cli")
            .join("config.json");

        let json_string = fs::read_to_string(user_config_file_path)?;
        let a: Configs = serde_json::from_str(&json_string)?;
        Ok(a)
    }
}