Skip to content

Commit b41894c

Browse files
authored
v2.1.1 - Better performance (#17)
* Improved performance A LOT. Other minor improvements * Updated program version
1 parent 933d704 commit b41894c

File tree

6 files changed

+142
-114
lines changed

6 files changed

+142
-114
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
authors = ["Marcos Gutiérrez Alonso <margual56@gmail.com>"]
33
description = "A simple radio cli for listening to your favourite streams from the console"
44
name = "radio-cli"
5-
version = "2.1.0"
5+
version = "2.1.1"
66
edition = "2021"
77
homepage = "https://github.com/margual56/radio-cli"
88
repository = "https://github.com/margual56/radio-cli"

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"config_version": "2.1.0",
2+
"config_version": "2.1.1",
33
"max_lines": 7,
44
"country": "ES",
55
"data": [

src/lib/browser.rs

Lines changed: 93 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,110 +2,109 @@ use std::error::Error;
22

33
use crate::{station::Station, Config};
44
use inquire::{error::InquireError, Text};
5-
use radiobrowser::{blocking::RadioBrowserAPI, ApiCountry, StationOrder};
5+
use radiobrowser::{blocking::RadioBrowserAPI, ApiCountry, ApiStation, StationOrder};
66

7-
pub fn get_countries() -> Result<Vec<ApiCountry>, Box<dyn Error>> {
8-
let api = match RadioBrowserAPI::new() {
9-
Ok(r) => r,
10-
Err(_e) => panic!("Failed to create Radio Browser API!"),
11-
};
12-
13-
api.get_countries().send()
7+
pub struct Browser {
8+
api: RadioBrowserAPI,
9+
config: Config,
10+
stations: Vec<ApiStation>,
1411
}
1512

16-
pub fn get_station(name: String, country_code: Option<String>) -> Result<Station, InquireError> {
17-
let api = match RadioBrowserAPI::new() {
18-
Ok(r) => r,
19-
Err(_e) => panic!("Failed to create Radio Browser API!"),
20-
};
13+
impl Browser {
14+
pub fn new(config: Config) -> Result<Browser, Box<dyn Error>> {
15+
let api = match RadioBrowserAPI::new() {
16+
Ok(r) => r,
17+
Err(e) => return Err(e),
18+
};
2119

22-
if let Some(code) = country_code {
23-
return match api.get_stations().name(name).countrycode(code).send() {
24-
Ok(s) => match s.get(0) {
25-
Some(x) => Ok(Station {
26-
station: x.name.clone(),
27-
url: x.url.clone(),
28-
}),
29-
None => Err(InquireError::InvalidConfiguration(
30-
"Radio station does not exist".to_string(),
31-
)),
32-
},
33-
Err(_e) => Err(InquireError::OperationInterrupted),
20+
let stations = if let Some(code) = &config.country_code {
21+
match api
22+
.get_stations()
23+
.countrycode(code)
24+
.order(StationOrder::Clickcount)
25+
.send()
26+
{
27+
Ok(s) => s,
28+
Err(_e) => Vec::new(),
29+
}
30+
} else {
31+
match api.get_stations().order(StationOrder::Clickcount).send() {
32+
Ok(s) => s,
33+
Err(_e) => Vec::new(),
34+
}
3435
};
35-
} else {
36-
return match api.get_stations().name(name).send() {
37-
Ok(s) => match s.get(0) {
38-
Some(x) => Ok(Station {
39-
station: x.name.clone(),
40-
url: x.url.clone(),
41-
}),
42-
None => Err(InquireError::InvalidConfiguration(
43-
"Radio station does not exist".to_string(),
44-
)),
45-
},
46-
Err(_e) => Err(InquireError::OperationInterrupted),
36+
37+
Ok(Browser {
38+
api,
39+
config,
40+
stations,
41+
})
42+
}
43+
44+
pub fn get_countries() -> Result<Vec<ApiCountry>, Box<dyn Error>> {
45+
let api = match RadioBrowserAPI::new() {
46+
Ok(r) => r,
47+
Err(e) => return Err(e),
4748
};
49+
50+
api.get_countries().send()
4851
}
49-
}
5052

51-
fn search_station(
52-
message: &str,
53-
placeholder: &str,
54-
country_code: Option<String>,
55-
) -> Result<String, InquireError> {
56-
let api = match RadioBrowserAPI::new() {
57-
Ok(r) => r,
58-
Err(_e) => panic!("Failed to create Radio Browser API!"),
59-
};
53+
pub fn get_station(&self, name: String) -> Result<Station, InquireError> {
54+
if let Some(code) = self.config.country_code.clone() {
55+
return match self.api.get_stations().name(name).countrycode(code).send() {
56+
Ok(s) => match s.get(0) {
57+
Some(x) => Ok(Station {
58+
station: x.name.clone(),
59+
url: x.url.clone(),
60+
}),
61+
None => Err(InquireError::InvalidConfiguration(
62+
"Radio station does not exist".to_string(),
63+
)),
64+
},
65+
Err(_e) => Err(InquireError::OperationInterrupted),
66+
};
67+
} else {
68+
return match self.api.get_stations().name(name).send() {
69+
Ok(s) => match s.get(0) {
70+
Some(x) => Ok(Station {
71+
station: x.name.clone(),
72+
url: x.url.clone(),
73+
}),
74+
None => Err(InquireError::InvalidConfiguration(
75+
"Radio station does not exist".to_string(),
76+
)),
77+
},
78+
Err(_e) => Err(InquireError::OperationInterrupted),
79+
};
80+
}
81+
}
6082

61-
Text::new(message)
62-
.with_placeholder(placeholder)
63-
.with_suggester(&|s: &str| {
64-
if s.len() > 3 {
65-
if let Some(code) = &country_code {
66-
match api
67-
.get_stations()
68-
.countrycode(code)
69-
.name(s)
70-
.order(StationOrder::Clickcount)
71-
.send()
72-
{
73-
Ok(s) => s
74-
.iter()
75-
.map(|station| String::from(&station.name))
76-
.collect(),
77-
Err(_e) => Vec::new(),
78-
}
79-
} else {
80-
match api
81-
.get_stations()
82-
.name(s)
83-
.order(StationOrder::Clickcount)
84-
.send()
85-
{
86-
Ok(s) => s
87-
.iter()
88-
.map(|station| String::from(&station.name))
89-
.collect(),
90-
Err(_e) => Vec::new(),
91-
}
92-
}
93-
} else {
94-
Vec::new()
95-
}
96-
})
97-
.prompt()
98-
}
83+
fn search_station(&self, message: &str, placeholder: &str) -> Result<String, InquireError> {
84+
let max_lines = match self.config.max_lines {
85+
Some(x) => x,
86+
None => Text::DEFAULT_PAGE_SIZE,
87+
};
88+
89+
Text::new(message)
90+
.with_placeholder(placeholder)
91+
.with_suggester(&|s: &str| {
92+
self.stations
93+
.iter()
94+
.filter(|station| station.name.contains(s))
95+
.map(|station| String::from(&station.name))
96+
.collect()
97+
})
98+
.with_page_size(max_lines)
99+
.prompt()
100+
}
99101

100-
pub fn prompt(config: Config) -> Result<Station, InquireError> {
101-
let station = search_station(
102-
"Search for a station: ",
103-
"Station name",
104-
config.country_code.clone(),
105-
);
102+
pub fn prompt(self) -> Result<Station, InquireError> {
103+
let station = self.search_station("Search for a station: ", "Station name");
106104

107-
match station {
108-
Ok(s) => get_station(s, config.country_code.clone()),
109-
Err(e) => Err(e),
105+
match station {
106+
Ok(s) => self.get_station(s.to_string()),
107+
Err(e) => Err(e),
108+
}
110109
}
111110
}

src/lib/config.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::fs::File;
1414
use std::io::{Read, Write};
1515
use std::path::PathBuf;
1616

17-
use crate::browser;
17+
use crate::browser::Browser;
1818

1919
const _CONFIG_URL: &str = "https://raw.githubusercontent.com/margual56/radio-cli/main/config.json";
2020

@@ -154,31 +154,45 @@ impl Config {
154154
return stations;
155155
}
156156

157-
pub fn prompt(self) -> Result<Station, InquireError> {
157+
/// Prompts the user to select a station.
158+
/// Returns a station and if the station was taken from the internet.
159+
pub fn prompt(self) -> Result<(Station, bool), InquireError> {
158160
let res: Result<Station, InquireError>;
159-
if let Some(lines) = self.max_lines {
160-
res = Select::new(&"Select a station to play:".bold(), self.data.clone())
161-
.with_page_size(lines)
162-
.prompt();
163-
} else {
164-
res = Select::new(&"Select a station to play:".bold(), self.data.clone()).prompt();
165-
}
166161

162+
let max_lines: usize = match self.max_lines {
163+
Some(x) => x,
164+
None => Select::<Station>::DEFAULT_PAGE_SIZE,
165+
};
166+
167+
res = Select::new(&"Select a station to play:".bold(), self.data.clone())
168+
.with_page_size(max_lines)
169+
.prompt();
170+
171+
let internet: bool;
167172
let station: Station = match res {
168173
Ok(s) => {
169174
if s.station.eq("Other") {
170-
match browser::prompt(self) {
175+
internet = true;
176+
let result = Browser::new(self);
177+
178+
let brow = match result {
179+
Ok(b) => b,
180+
Err(_e) => return Err(InquireError::OperationInterrupted),
181+
};
182+
183+
match brow.prompt() {
171184
Ok(r) => r,
172185
Err(e) => return Err(e),
173186
}
174187
} else {
188+
internet = false;
175189
s
176190
}
177191
}
178192
Err(e) => return Err(e),
179193
};
180194

181-
return Ok(station);
195+
return Ok((station, internet));
182196
}
183197
}
184198

src/main.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub use clap::Parser;
22
use colored::*;
3-
use radio_libs::{browser, perror, Config, ConfigError, Station, Version};
3+
use radio_libs::browser::Browser;
4+
use radio_libs::{perror, Config, ConfigError, Station, Version};
45
use std::io::Write;
56
use std::path::PathBuf;
67
use std::process::{Command, Stdio};
@@ -78,9 +79,7 @@ fn main() {
7879
let args = Cli::parse();
7980

8081
if args.list_countries {
81-
let result = browser::get_countries();
82-
83-
if let Ok(countries) = result {
82+
if let Ok(countries) = Browser::get_countries() {
8483
for country in countries {
8584
println!("{}: \"{}\"", country.name, country.iso_3166_1.bold());
8685
}
@@ -177,7 +176,20 @@ fn main() {
177176

178177
internet = true;
179178

180-
match browser::get_station(x.clone(), config.country_code.clone()) {
179+
let brows = match Browser::new(config) {
180+
Ok(b) => b,
181+
Err(e) => {
182+
perror("Could not connect with the API");
183+
184+
if args.debug {
185+
println!("{}", e);
186+
}
187+
188+
std::process::exit(1);
189+
}
190+
};
191+
192+
match brows.get_station(x.clone()) {
181193
Ok(s) => s.url,
182194
Err(e) => {
183195
perror("This station was not found :(");
@@ -199,7 +211,10 @@ fn main() {
199211
None => {
200212
// And let the user choose one
201213
match config.clone().prompt() {
202-
Ok(s) => s,
214+
Ok((s, b)) => {
215+
internet = b;
216+
s
217+
}
203218
Err(error) => {
204219
println!("\n\t{}", "Bye!".bold().green());
205220

0 commit comments

Comments
 (0)