1use colorized::Colors;
2use dirs;
3use serde::{Deserialize, Serialize};
4use std::error::Error;
5use std::fs;
6
7use unicode_segmentation::UnicodeSegmentation;
8
9use crate::actions::gnrm::RegistryManager;
10
11trait CharSize {
12 fn len(str: &str) -> usize {
13 let graphemes = UnicodeSegmentation::graphemes(str, true).collect::<Vec<&str>>();
14 graphemes.len()
15 }
16}
17
18#[derive(Serialize, Deserialize, Debug, Clone)]
19pub struct User {
20 pub name: String,
21 pub email: String,
22 pub alias: String,
23}
24impl User {
25 pub fn format(&self, len: usize, is_current: bool) -> String {
26 let start_len = User::len(&self.alias) + User::len(&self.name);
27 let end_len = User::len(&self.email);
28 let len = len - start_len - end_len;
29 let current = if is_current {
30 colorized::colorize_this("■", Colors::GreenFg)
31 } else {
32 String::from(" ")
33 };
34 format!(
35 " {} {}({}){}{}",
36 current,
37 self.alias,
38 colorized::colorize_this(&self.name, Colors::WhiteFg),
39 String::from("-").repeat(len),
40 self.email
41 )
42 }
43
44 pub fn max_size(users: &Vec<User>) -> usize {
45 let mut max = 0;
46 for itme in users.iter() {
47 let length = User::len(&itme.name) + User::len(&itme.alias) + User::len(&itme.email);
48 max = if max < length { length } else { max }
49 }
50 max
51 }
52}
53
54impl CharSize for User {}
55
56#[derive(Serialize, Deserialize, Debug, Clone)]
57pub struct Registry {
58 pub name: String,
59 pub alias: String,
60 pub home: String,
61 pub registry: String,
62}
63
64impl CharSize for Registry {}
65
66impl Registry {
67 pub fn format(&self, len: usize, manager: &RegistryManager, list_max_len: usize) -> String {
68 let is_some = if &self.alias == &self.name {
69 true
70 } else {
71 false
72 };
73 let sart_text = if is_some {
74 self.alias.to_owned()
75 } else {
76 format!("{}({})", &self.alias, &self.name)
77 };
78 let start_len = Registry::len(&sart_text);
79 let end_len = Registry::len(&self.registry);
80 let len = len - start_len - end_len;
81 let current = manager.get(&self.registry);
82
83 let mut cur_display = current.join(" ");
84 let real_len = Registry::len(¤t.join(""));
85
86 let magic = if cur_display.is_empty() {
87 list_max_len * 2
88 } else {
89 list_max_len * 2 - (real_len / 10) + 1
90 };
91
92 if real_len / 10 < magic {
93 cur_display.push_str(&" ".repeat(magic - real_len / 10))
94 }
95 format!(
96 "{}{}{}{}",
97 cur_display,
98 sart_text,
99 String::from("-").repeat(len),
100 self.registry
101 )
102 }
103
104 pub fn max_size(registry: &Vec<Registry>) -> usize {
105 let mut max = 0;
106 for itme in registry.iter() {
107 let length = Registry::len(&itme.name)
108 + Registry::len(&itme.alias)
109 + Registry::len(&itme.registry);
110 max = if max < length { length } else { max }
111 }
112 max
113 }
114}
115
116#[derive(Serialize, Deserialize, Debug)]
117pub struct GacmConfig {
118 pub version: String,
119 pub users: Vec<User>,
120 pub registry: Vec<Registry>,
121 pub is_load: Option<bool>,
122}
123
124impl GacmConfig {
125 pub fn new() -> GacmConfig {
126 GacmConfig {
127 version: String::from("0.0.1"),
128 registry: Vec::new(),
129 users: Vec::new(),
130 is_load: Some(false),
131 }
132 }
133 pub fn load(&mut self) -> Result<&GacmConfig, Box<dyn Error>> {
134 match self.is_load {
135 Some(false) => {
136 let home_dir = dirs::home_dir().unwrap();
137 let config_str = fs::read_to_string(home_dir.join(".gacmrc"))?;
138 let config: GacmConfig = serde_json::from_str(&config_str)?;
139 self.users = config.users;
140 self.registry = config.registry;
141 self.version = config.version;
142 self.is_load = Some(true);
143 Ok(self)
144 }
145 _ => Ok(self),
146 }
147 }
148
149 pub fn get_use_config(&self) -> &Vec<User> {
150 &self.users
151 }
152 pub fn get_registry_config(&self) -> &Vec<Registry> {
153 &self.registry
154 }
155}