Skip to content

Commit fc87440

Browse files
authored
Merge pull request #8 from fufexan/lints
chore: apply clippy lints
2 parents 344c9ba + e65bfa9 commit fc87440

File tree

11 files changed

+110
-120
lines changed

11 files changed

+110
-120
lines changed

src/clipboard.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use arboard::Clipboard;
22

3-
pub fn copy_to_clipboard(text: &str) -> Result<(), arboard::Error> {
3+
pub fn copy(text: &str) -> Result<(), arboard::Error> {
44
let mut clipboard = Clipboard::new()?;
55
clipboard.set_text(text)
66
}
77

8-
pub fn get_from_clipboard() -> Result<String, arboard::Error> {
8+
pub fn get() -> Result<String, arboard::Error> {
99
let mut clipboard = Clipboard::new()?;
1010
clipboard.get_text()
1111
}

src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ fn main() {
1313

1414
// start tray service
1515
match start_tray_service() {
16-
Ok(_) => println!("Tray service started successfully."),
17-
Err(e) => eprintln!("Failed to start the tray service: {}", e),
16+
Ok(()) => println!("Tray service started successfully."),
17+
Err(e) => eprintln!("Failed to start the tray service: {e}"),
1818
}
1919

2020
// keep the main thread alive

src/pkexec.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ use std::path::PathBuf;
22
use which::which;
33
use whoami::username;
44

5-
pub fn get_pkexec_path() -> PathBuf {
6-
match which("pkexec") {
7-
Ok(path) => path,
8-
Err(_) => panic!("pkexec not found in PATH"),
9-
}
5+
pub fn get_path() -> PathBuf {
6+
which("pkexec").unwrap_or_else(|_| panic!("pkexec not found in PATH"))
107
}
118

129
// We don't need to elevate privileges if we're using the Tray service
1310
// as the root user. This shouldn't really happen, but it's possible
1411
// depending on how Tailran is ran.
1512
pub fn should_elevate_perms() -> bool {
16-
let parent_user = username().to_string();
13+
let parent_user = username();
1714

1815
if parent_user.eq("root") {
1916
return false;

src/svg/renderer.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,25 @@ use resvg::{
77

88
const SVG_DATA: &str = include_str!("assets/tailscale.svg");
99

10-
pub struct ResvgRenderer {
10+
pub struct Resvg {
1111
options: Options,
1212
transform: Transform,
1313
font_db: fontdb::Database,
1414
}
1515

16-
impl ResvgRenderer {
17-
pub fn to_icon(&mut self, svg_str: &str) -> Icon {
16+
impl Resvg {
17+
#[allow(clippy::cast_sign_loss)]
18+
#[allow(clippy::cast_possible_truncation)]
19+
pub fn to_icon(&self, svg_str: &str) -> Icon {
1820
let rtree = Tree::from_str(svg_str, &self.options, &self.font_db).unwrap_or_else(|e| {
19-
panic!("Failed to parse SVG: {}", e);
21+
panic!("Failed to parse SVG: {e}");
2022
});
2123

2224
let size = rtree.size();
25+
let width = size.width() as u32;
26+
let height = size.height() as u32;
2327

24-
let mut pixmap =
25-
Pixmap::new(size.width().round() as u32, size.height().round() as u32).unwrap();
28+
let mut pixmap = Pixmap::new(width, height).unwrap();
2629

2730
resvg::render(&rtree, self.transform, &mut pixmap.as_mut());
2831

@@ -33,28 +36,25 @@ impl ResvgRenderer {
3336
.collect();
3437

3538
Icon {
36-
width: size.width().round() as i32,
37-
height: size.height().round() as i32,
39+
width: size.width() as i32,
40+
height: size.height() as i32,
3841
data: argb_data,
3942
}
4043
}
4144

4245
pub fn load_icon(enabled: bool) -> Vec<Icon> {
43-
let mut renderer = ResvgRenderer {
46+
let renderer = Self {
4447
options: Options::default(),
4548
transform: Transform::default(),
4649
font_db: fontdb::Database::new(),
4750
};
4851

49-
match enabled {
50-
true => {
51-
log::debug!("icon: Tailscale is enabled");
52-
vec![renderer.to_icon(&SVG_DATA)]
53-
}
54-
false => {
55-
log::debug!("icon: Tailscale is not enabled");
56-
vec![renderer.to_icon(&SVG_DATA.replace("1.0", "0.4"))]
57-
}
52+
if enabled {
53+
log::debug!("icon: Tailscale is enabled");
54+
vec![renderer.to_icon(SVG_DATA)]
55+
} else {
56+
log::debug!("icon: Tailscale is not enabled");
57+
vec![renderer.to_icon(&SVG_DATA.replace("1.0", "0.4"))]
5858
}
5959
}
6060
}

src/tailscale/dns.rs

-9
This file was deleted.

src/tailscale/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
pub mod dns;
21
pub mod peer;
32
pub mod status;
43
pub mod utils;

src/tailscale/peer.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
use crate::clipboard::{copy_to_clipboard, get_from_clipboard};
2-
use log::{error, info};
1+
use crate::clipboard::{copy, get};
32
use notify_rust::Notification;
43

54
pub fn check_peer_ip(peer_ip: &str) {
65
if peer_ip.is_empty() {
7-
error!("No peer IP.")
6+
log::error!("No peer IP.");
87
} else {
9-
info!("Peer IP: {}", peer_ip);
8+
log::info!("Peer IP: {peer_ip}");
109
}
1110
}
1211

@@ -17,21 +16,21 @@ pub fn copy_peer_ip(
1716
) -> Result<(), Box<dyn std::error::Error>> {
1817
check_peer_ip(peer_ip);
1918

20-
copy_to_clipboard(peer_ip)?;
19+
copy(peer_ip)?;
2120

2221
// Get IP from clipboard to verify
23-
let clip_ip = get_from_clipboard()?;
22+
let clip_ip = get()?;
2423

2524
// Create summary for host/peer
2625
let summary = format!("Copied {} IP address", if host { "host" } else { "peer" });
2726

2827
// log success
29-
info!("{} {} to the clipboard", summary, clip_ip);
28+
log::info!("{summary} {clip_ip} to the clipboard");
3029

3130
// send a notification through dbus
3231
Notification::new()
3332
.summary(&summary)
34-
.body(&notif_body)
33+
.body(notif_body)
3534
.icon("tailscale")
3635
.show()?;
3736

src/tailscale/status.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::tailscale::dns;
1+
use crate::tailscale::utils;
22
use crate::tailscale::utils::{Machine, User};
33
use crate::tray::menu::Context;
44
use serde::{Deserialize, Serialize};
@@ -22,23 +22,23 @@ pub struct Status {
2222
user: HashMap<String, User>,
2323
}
2424

25-
pub fn get_status() -> Result<Status, Box<dyn std::error::Error>> {
26-
let status_json = get_status_json()?;
25+
pub fn get() -> Result<Status, Box<dyn std::error::Error>> {
26+
let status_json = get_json()?;
2727
let mut status: Status = serde_json::from_str(&status_json)?;
28-
let dnssuffix = status.magic_dnssuffix.to_owned();
28+
let dnssuffix = &status.magic_dnssuffix;
2929
status.tailscale_up = matches!(status.backend_state.as_str(), "Running");
3030

31-
dns::dns_or_quote_hostname(&mut status.this_machine, &dnssuffix);
31+
utils::set_display_name(&mut status.this_machine, dnssuffix);
3232
status
3333
.peers
3434
.values_mut()
35-
.for_each(|m| dns::dns_or_quote_hostname(m, &dnssuffix));
35+
.for_each(|m| utils::set_display_name(m, dnssuffix));
3636

3737
Ok(status)
3838
}
3939

40-
pub fn get_current_status() -> Result<Context, Box<dyn std::error::Error>> {
41-
let status = get_status()?;
40+
pub fn get_current() -> Result<Context, Box<dyn std::error::Error>> {
41+
let status = get()?;
4242
let pkexec = which("pkexec")?;
4343

4444
Ok(Context {
@@ -48,7 +48,7 @@ pub fn get_current_status() -> Result<Context, Box<dyn std::error::Error>> {
4848
})
4949
}
5050

51-
pub fn get_status_json() -> Result<String, Box<dyn std::error::Error>> {
51+
pub fn get_json() -> Result<String, Box<dyn std::error::Error>> {
5252
let output = Command::new("tailscale")
5353
.arg("status")
5454
.arg("--json")

src/tailscale/utils.rs

+42-37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use serde::{Deserialize, Serialize};
22
use std::{
3-
collections::HashMap,
3+
collections::HashSet,
44
fmt::{Display, Formatter},
55
};
66

@@ -12,15 +12,15 @@ pub enum PeerKind {
1212

1313
impl Default for PeerKind {
1414
fn default() -> Self {
15-
PeerKind::HostName("default".to_owned())
15+
Self::HostName("default".to_owned())
1616
}
1717
}
1818

1919
impl Display for PeerKind {
2020
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2121
match &self {
22-
PeerKind::DNSName(d) => write!(f, "{d}"),
23-
PeerKind::HostName(h) => write!(f, "{h}"),
22+
Self::DNSName(d) => write!(f, "{d}"),
23+
Self::HostName(h) => write!(f, "{h}"),
2424
}
2525
}
2626
}
@@ -62,50 +62,55 @@ pub fn has_suffix(name: &str, suffix: &str) -> bool {
6262
pub fn trim_suffix(name: &str, suffix: &str) -> String {
6363
let mut new_name = name;
6464
if has_suffix(name, suffix) {
65-
new_name = new_name.trim_end_matches('.');
6665
let suffix = suffix.trim_start_matches('.').trim_end_matches('.');
66+
new_name = new_name.trim_end_matches('.');
6767
new_name = new_name.trim_end_matches(suffix);
6868
}
6969
new_name.trim_end_matches('.').to_string()
7070
}
7171

7272
pub fn sanitize_hostname(hostname: &str) -> String {
73-
const MAX_LABEL_LEN: usize = 63;
74-
let mut sb = "".to_string();
73+
const MAX_LABEL_LENGTH: usize = 63;
74+
75+
// Trim suffixes
7576
let hostname = hostname
7677
.trim_end_matches(".local")
7778
.trim_end_matches(".localdomain")
7879
.trim_end_matches(".lan");
79-
let mut start = 0;
80-
let mut end = hostname.len();
81-
if end > MAX_LABEL_LEN {
82-
end = MAX_LABEL_LEN;
83-
}
84-
let mut chars = hostname.chars();
85-
while start < end {
86-
if chars.nth(start).unwrap().is_alphanumeric() {
87-
break;
88-
}
89-
start += 1;
90-
}
91-
while start < end {
92-
if chars.nth(end - 1).unwrap().is_alphanumeric() {
93-
break;
94-
}
95-
end -= 1;
96-
}
97-
let seperators: HashMap<char, bool> =
98-
HashMap::from([(' ', true), ('.', true), ('@', true), ('_', true)]);
9980

100-
let mut chars = hostname.chars();
101-
for i in start..end - 1 {
102-
let boundary = (i == start) || (i == end - 1);
103-
let chari = chars.nth(i).unwrap();
104-
if !boundary && seperators[&chari] {
105-
sb.push('-');
106-
} else if chari.is_alphanumeric() || chari == '-' {
107-
sb.push(chari.to_ascii_lowercase())
108-
}
81+
// Find the first/last alphanumeric characters
82+
let start = hostname.find(|c: char| c.is_alphanumeric()).unwrap_or(0);
83+
let end = hostname
84+
.rfind(|c: char| c.is_alphanumeric())
85+
.map_or(0, |e| e + 1);
86+
87+
let separators: HashSet<char> = [' ', '.', '@', '_'].into();
88+
89+
let mut sanitized: String = hostname[start..end]
90+
.chars()
91+
.enumerate()
92+
.map(|(index, char)| {
93+
let boundary = (index == 0) || (index == end - start - 1);
94+
if !boundary && separators.contains(&char) {
95+
'-'
96+
} else if char.is_alphanumeric() || char == '-' {
97+
char.to_ascii_lowercase()
98+
} else {
99+
char
100+
}
101+
})
102+
.collect();
103+
104+
sanitized.truncate(MAX_LABEL_LENGTH);
105+
sanitized
106+
}
107+
108+
pub fn set_display_name(m: &mut Machine, dns_suffix: &str) {
109+
let dns_name = trim_suffix(&m.dns_name, dns_suffix);
110+
111+
if dns_name.is_empty() {
112+
m.display_name = PeerKind::DNSName(sanitize_hostname(&m.hostname));
113+
} else {
114+
m.display_name = PeerKind::HostName(dns_name);
109115
}
110-
sb
111116
}

0 commit comments

Comments
 (0)