forked from hykilpikonna/hyfetch
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c874a8
commit 5cdc0d6
Showing
6 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
use std::path::Path; | ||
use std::{env, fs}; | ||
|
||
use indexmap::IndexMap; | ||
use regex::Regex; | ||
use unicode_normalization::UnicodeNormalization; | ||
|
||
#[derive(Debug)] | ||
struct AsciiDistro { | ||
pattern: String, | ||
art: String, | ||
} | ||
|
||
impl AsciiDistro { | ||
fn friendly_name(&self) -> String { | ||
self.pattern | ||
.split('|') | ||
.next() | ||
.expect("invalid distro pattern") | ||
.trim_matches(|c: char| c.is_ascii_punctuation() || c == ' ') | ||
.replace(['"', '*'], "") | ||
} | ||
} | ||
|
||
fn main() { | ||
let neofetch_path = Path::new(env!("CARGO_WORKSPACE_DIR")).join("neofetch"); | ||
|
||
println!("cargo:rerun-if-changed={}", neofetch_path.display()); | ||
|
||
let out_dir = env::var("OUT_DIR").unwrap(); | ||
let out_path = Path::new(&out_dir); | ||
|
||
export_distros(neofetch_path, out_path); | ||
} | ||
|
||
fn export_distros<P>(neofetch_path: P, out_path: &Path) | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
let distros = parse_ascii_distros(neofetch_path); | ||
let mut variants = IndexMap::with_capacity(distros.len()); | ||
|
||
for distro in &distros { | ||
let variant = distro | ||
.friendly_name() | ||
.replace(|c: char| c.is_ascii_punctuation() || c == ' ', "_") | ||
.nfc() | ||
.collect::<String>(); | ||
variants.insert(variant, distro); | ||
} | ||
|
||
let mut buf = " | ||
#[derive(Clone, Eq, PartialEq, Hash, Debug)] | ||
pub enum Distro { | ||
" | ||
.to_owned(); | ||
|
||
for (variant, distro) in &variants { | ||
buf.push_str(&format!( | ||
" | ||
// {}) | ||
{variant}, | ||
", | ||
distro.pattern | ||
)); | ||
} | ||
|
||
buf.push_str( | ||
" | ||
} | ||
", | ||
); | ||
|
||
buf.push_str( | ||
" | ||
impl Distro { | ||
pub fn ascii_art(&self) -> &str { | ||
(match self { | ||
", | ||
); | ||
|
||
let quotes = "#".repeat(80); | ||
for (variant, distro) in &variants { | ||
buf.push_str(&format!( | ||
" | ||
Self::{variant} => r{quotes}\" | ||
{} | ||
\"{quotes}, | ||
", | ||
distro.art | ||
)); | ||
} | ||
|
||
buf.push_str( | ||
" | ||
}) | ||
.trim() | ||
} | ||
} | ||
", | ||
); | ||
|
||
fs::write(out_path.join("distros.rs"), buf).expect("couldn't write distros.rs"); | ||
} | ||
|
||
/// Parses ascii distros from neofetch script. | ||
fn parse_ascii_distros<P>(neofetch_path: P) -> Vec<AsciiDistro> | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
let neofetch_path = neofetch_path.as_ref(); | ||
|
||
let nf = { | ||
let nf = fs::read_to_string(neofetch_path).expect("couldn't read neofetch script"); | ||
|
||
// Get the content of "get_distro_ascii" function | ||
let (_, nf) = nf | ||
.split_once("get_distro_ascii() {\n") | ||
.expect("couldn't find get_distro_ascii function"); | ||
let (nf, _) = nf | ||
.split_once("\n}\n") | ||
.expect("couldn't find end of get_distro_ascii function"); | ||
|
||
let mut nf = nf.replace('\t', &" ".repeat(4)); | ||
|
||
// Remove trailing spaces | ||
while nf.contains(" \n") { | ||
nf = nf.replace(" \n", "\n"); | ||
} | ||
nf | ||
}; | ||
|
||
let case_re = Regex::new(r"case .*? in\n").expect("couldn't compile case regex"); | ||
let eof_re = Regex::new(r"EOF[ \n]*?;;").expect("couldn't compile eof regex"); | ||
|
||
// Split by blocks | ||
let mut blocks = vec![]; | ||
for b in case_re.split(&nf) { | ||
blocks.extend(eof_re.split(b).map(|sub| sub.trim())); | ||
} | ||
|
||
// Parse blocks | ||
fn parse_block(block: &str) -> Option<AsciiDistro> { | ||
let (block, art) = block.split_once("'EOF'\n")?; | ||
|
||
// Join \ | ||
// | ||
// > A <backslash> that is not quoted shall preserve the literal value of the | ||
// > following character, with the exception of a <newline>. If a <newline> | ||
// > follows the <backslash>, the shell shall interpret this as line | ||
// > continuation. The <backslash> and <newline> shall be removed before | ||
// > splitting the input into tokens. Since the escaped <newline> is removed | ||
// > entirely from the input and is not replaced by any white space, it cannot | ||
// > serve as a token separator. | ||
// See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_01 | ||
let block = block.replace("\\\n", ""); | ||
|
||
// Get case pattern | ||
let pattern = block | ||
.split('\n') | ||
.next() | ||
.and_then(|pattern| pattern.trim().strip_suffix(')'))?; | ||
|
||
Some(AsciiDistro { | ||
pattern: pattern.to_owned(), | ||
art: art.to_owned(), | ||
}) | ||
} | ||
blocks | ||
.iter() | ||
.filter_map(|block| parse_block(block)) | ||
.collect() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#![allow(non_camel_case_types)] | ||
|
||
include!(concat!(env!("OUT_DIR"), "/distros.rs")); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
pub mod cli_options; | ||
pub mod color_util; | ||
pub mod distros; | ||
pub mod neofetch_util; | ||
pub mod presets; | ||
pub mod types; |