Skip to content

Commit a57ba51

Browse files
committed
Make sources case-insensitive; closes #10
1 parent 4cca3ba commit a57ba51

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

foreman.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[tools]
2-
rojo = { source = "rojo-rbx/rojo", version = "0.5.0" }
2+
rojo = { source = "rojo-rbx/rojo", version = "0.5.0" }
3+
rojo2 = { source = "rOjO-rBx/rOjo", version = "0.5.0" }

src/ci_string.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use std::{
2+
fmt,
3+
hash::{Hash, Hasher},
4+
};
5+
6+
use serde::{Deserialize, Serialize};
7+
8+
/// Case-insensitive string.
9+
///
10+
/// A string that acts case-insensitive when compared or hashed, but preserves
11+
/// its case.
12+
#[derive(Debug, Clone, Serialize, Deserialize)]
13+
#[serde(transparent)]
14+
pub struct CiString(pub String);
15+
16+
impl fmt::Display for CiString {
17+
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
18+
formatter.write_str(&self.0)
19+
}
20+
}
21+
22+
impl Hash for CiString {
23+
fn hash<H: Hasher>(&self, state: &mut H) {
24+
let mut buf = [0; 4];
25+
for outer in self.0.chars() {
26+
for normalized in outer.to_lowercase() {
27+
normalized.encode_utf8(&mut buf);
28+
state.write(&buf);
29+
}
30+
}
31+
32+
state.write_u8(0xff);
33+
}
34+
}
35+
36+
impl PartialEq for CiString {
37+
fn eq(&self, other: &Self) -> bool {
38+
self.0
39+
.chars()
40+
.flat_map(char::to_lowercase)
41+
.eq(other.0.chars().flat_map(char::to_lowercase))
42+
}
43+
}
44+
45+
impl Eq for CiString {}

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod aliaser;
22
mod artifact_choosing;
33
mod auth_store;
4+
mod ci_string;
45
mod config;
56
mod fs;
67
mod github;

src/tool_cache.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use zip::ZipArchive;
1212

1313
use crate::{
1414
artifact_choosing::platform_keywords,
15+
ci_string::CiString,
1516
fs::{self, File},
1617
github, paths,
1718
};
@@ -25,7 +26,7 @@ fn index_file() -> PathBuf {
2526
/// Contains the current state of all of the tools that Foreman manages.
2627
#[derive(Debug, Default, Serialize, Deserialize)]
2728
pub struct ToolCache {
28-
pub tools: HashMap<String, ToolEntry>,
29+
pub tools: HashMap<CiString, ToolEntry>,
2930
}
3031

3132
impl ToolCache {
@@ -47,7 +48,7 @@ impl ToolCache {
4748
pub fn download_if_necessary(source: &str, version_req: &VersionReq) -> Option<Version> {
4849
let cache = Self::load().unwrap();
4950

50-
if let Some(tool) = cache.tools.get(source) {
51+
if let Some(tool) = cache.tools.get(&CiString(source.to_owned())) {
5152
log::debug!("Tool has some versions installed");
5253

5354
let matching_version = tool
@@ -133,7 +134,7 @@ impl ToolCache {
133134

134135
log::trace!("Updating tool cache");
135136
let mut cache = Self::load().unwrap();
136-
let tool = cache.tools.entry(source.to_owned()).or_default();
137+
let tool = cache.tools.entry(CiString(source.to_owned())).or_default();
137138
tool.versions.insert(version.clone());
138139
cache.save().unwrap();
139140

0 commit comments

Comments
 (0)