Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrofitted to pure Rust #58

Merged
merged 11 commits into from
Nov 13, 2023
Prev Previous commit
Next Next commit
style: remove trailing comma
7sDream committed Nov 12, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 3506921465e558a9f12109302cb09bb419f7af05
1 change: 0 additions & 1 deletion clippy.toml
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ disallowed-names = []
too-many-arguments-threshold = 5
too-large-for-stack = 256
enum-variant-name-threshold = 0
struct-field-name-threshold = 0
enum-variant-size-threshold = 256
too-many-lines-threshold = 50
array-size-threshold = 262144 # 256KB
1 change: 0 additions & 1 deletion rustfmt.toml
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ reorder_impl_items = true
group_imports = "StdExternalCrate"
reorder_modules = false
# short_array_element_width_threshold = 20
trailing_comma = "Always"
use_field_init_shorthand = true
use_small_heuristics = "Max"
use_try_shorthand = true
75 changes: 37 additions & 38 deletions src/font.rs
Original file line number Diff line number Diff line change
@@ -26,93 +26,92 @@ use std::{
use super::loader::{FontInfo, FontSet};
use crate::loader;

pub struct Family<'a, 'db,> {
pub struct Family<'a, 'db> {
pub name: &'a str,
pub fonts: BinaryHeap<Reverse<Font<'a, 'db,>,>,>,
pub fonts: BinaryHeap<Reverse<Font<'a, 'db>>>,
pub default_name_width: usize,
}

impl<'a, 'db: 'a,> Family<'a, 'db,> {
pub fn new(name: &'a str,) -> Self {
Self { name, fonts: BinaryHeap::new(), default_name_width: name.len(), }
impl<'a, 'db: 'a> Family<'a, 'db> {
pub fn new(name: &'a str) -> Self {
Self { name, fonts: BinaryHeap::new(), default_name_width: name.len() }
}

pub fn styles_count(&self,) -> usize {
pub fn styles_count(&self) -> usize {
self.fonts.len()
}

pub fn add_font(&mut self, font: Font<'a, 'db,>,) -> &mut Self {
self.fonts.push(Reverse(font,),);
pub fn add_font(&mut self, font: Font<'a, 'db>) -> &mut Self {
self.fonts.push(Reverse(font));
self
}
}

pub struct Font<'a, 'db,>(pub &'a loader::FontInfo<'db,>,);
pub struct Font<'a, 'db>(pub &'a loader::FontInfo<'db>);

impl<'a, 'db,> PartialEq for Font<'a, 'db,> {
fn eq(&self, other: &Self,) -> bool {
impl<'a, 'db> PartialEq for Font<'a, 'db> {
fn eq(&self, other: &Self) -> bool {
self.0.fullname() == other.0.fullname()
}
}

impl<'a, 'db,> Eq for Font<'a, 'db,> {}
impl<'a, 'db> Eq for Font<'a, 'db> {}

/// Implement `Ord` trait for store `FontInfo` in `BinaryHeap` struct
impl<'a, 'db,> Ord for Font<'a, 'db,> {
fn cmp(&self, other: &Self,) -> Ordering {
self.0.fullname().cmp(other.0.fullname(),)
impl<'a, 'db> Ord for Font<'a, 'db> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.fullname().cmp(other.0.fullname())
}
}

impl<'a, 'db,> PartialOrd for Font<'a, 'db,> {
fn partial_cmp(&self, other: &Self,) -> Option<Ordering,> {
Some(self.cmp(other,),)
impl<'a, 'db> PartialOrd for Font<'a, 'db> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl<'a, 'db,> TryFrom<&'a FontInfo<'db,>,> for Font<'a, 'db,> {
impl<'a, 'db> TryFrom<&'a FontInfo<'db>> for Font<'a, 'db> {
type Error = ();

fn try_from(font_info: &'a FontInfo<'db,>,) -> Result<Self, Self::Error,> {
Ok(Self(font_info,),)
fn try_from(font_info: &'a FontInfo<'db>) -> Result<Self, Self::Error> {
Ok(Self(font_info))
}
}

pub struct SortedFamilies<'a, 'db,>(Vec<Family<'a, 'db,>,>,);
pub struct SortedFamilies<'a, 'db>(Vec<Family<'a, 'db>>);

impl<'a, 'db: 'a,> From<&'a loader::FontSet<'db,>,> for SortedFamilies<'a, 'db,> {
fn from(font_set: &'a FontSet<'db,>,) -> Self {
impl<'a, 'db: 'a> From<&'a loader::FontSet<'db>> for SortedFamilies<'a, 'db> {
fn from(font_set: &'a FontSet<'db>) -> Self {
let mut families = HashMap::new();

font_set.fonts().iter().for_each(|fc_font| {
if let Ok(font,) = Font::try_from(fc_font,) {
if let Ok(font) = Font::try_from(fc_font) {
let family = font.0.family_name();
families.entry(family,).or_insert_with(|| Family::new(family,),).add_font(font,);
families.entry(family).or_insert_with(|| Family::new(family)).add_font(font);
}
},);
});

let mut families: Vec<Family<'a, 'db,>,> =
families.into_iter().map(|(_, family,)| family,).collect();
let mut families: Vec<Family<'a, 'db>> = families.into_values().collect();

families.sort_by_key(|f| f.name,);
families.sort_by_key(|f| f.name);

Self(families,)
Self(families)
}
}

impl<'a, 'db,> IntoIterator for SortedFamilies<'a, 'db,> {
type IntoIter = <Vec<Family<'a, 'db,>,> as IntoIterator>::IntoIter;
type Item = <Vec<Family<'a, 'db,>,> as IntoIterator>::Item;
impl<'a, 'db> IntoIterator for SortedFamilies<'a, 'db> {
type IntoIter = <Vec<Family<'a, 'db>> as IntoIterator>::IntoIter;
type Item = <Vec<Family<'a, 'db>> as IntoIterator>::Item;

fn into_iter(self,) -> Self::IntoIter {
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}

impl<'a, 'db,> Deref for SortedFamilies<'a, 'db,> {
type Target = Vec<Family<'a, 'db,>,>;
impl<'a, 'db> Deref for SortedFamilies<'a, 'db> {
type Target = Vec<Family<'a, 'db>>;

fn deref(&self,) -> &Self::Target {
fn deref(&self) -> &Self::Target {
&self.0
}
}
6 changes: 3 additions & 3 deletions src/loader/charset.rs
Original file line number Diff line number Diff line change
@@ -19,11 +19,11 @@
use std::collections::HashSet;

#[derive(Default)]
pub struct Charset(HashSet<char,>,);
pub struct Charset(HashSet<char>);

impl Charset {
pub fn add_char(mut self, c: char,) -> Self {
self.0.insert(c,);
pub fn add_char(mut self, c: char) -> Self {
self.0.insert(c);
self
}
}
14 changes: 7 additions & 7 deletions src/loader/font_info.rs
Original file line number Diff line number Diff line change
@@ -19,29 +19,29 @@
use std::path::{Path, PathBuf};

/// This struct is a convenient type to represent fonts in `FontSet`'s font array.
pub struct FontInfo<'db,> {
pub struct FontInfo<'db> {
pub id: fontdb::ID,
pub path: PathBuf,
pub index: u32,
pub family: String,
pub name: String,
pub cmap: Vec<owned_ttf_parser::cmap::Subtable<'db,>,>,
pub cmap: Vec<owned_ttf_parser::cmap::Subtable<'db>>,
}

impl<'font,> FontInfo<'font,> {
pub fn family_name(&self,) -> &str {
impl<'font> FontInfo<'font> {
pub fn family_name(&self) -> &str {
&self.family
}

pub fn fullname(&self,) -> &str {
pub fn fullname(&self) -> &str {
&self.name
}

pub fn path(&self,) -> &Path {
pub fn path(&self) -> &Path {
self.path.as_path()
}

pub fn index(&self,) -> u32 {
pub fn index(&self) -> u32 {
self.index
}
}
16 changes: 8 additions & 8 deletions src/loader/font_set.rs
Original file line number Diff line number Diff line change
@@ -21,12 +21,12 @@ use std::path::PathBuf;
use super::{FontInfo, Pattern};
use crate::loader::DATABASE;

pub struct FontSet<'db,> {
fonts: Vec<FontInfo<'db,>,>,
pub struct FontSet<'db> {
fonts: Vec<FontInfo<'db>>,
}

impl<'db,> FontSet<'db,> {
pub fn match_pattern(pattern: &Pattern,) -> Self {
impl<'db> FontSet<'db> {
pub fn match_pattern(_pattern: &Pattern) -> Self {
Self {
fonts: DATABASE
.faces()
@@ -35,16 +35,16 @@ impl<'db,> FontSet<'db,> {
id: f.id,
path: PathBuf::default(),
index: f.index,
family: f.families.get(0,).map(|(s, _,)| s.clone(),)?,
family: f.families.get(0).map(|(s, _)| s.clone())?,
name: f.post_script_name.clone(),
cmap: vec![],
},)
},)
})
})
.collect(),
}
}

pub fn fonts<'fs,>(&self,) -> &[FontInfo<'db,>] {
pub fn fonts<'fs>(&self) -> &[FontInfo<'db>] {
self.fonts.as_slice()
}
}
6 changes: 3 additions & 3 deletions src/loader/mod.rs
Original file line number Diff line number Diff line change
@@ -27,10 +27,10 @@ pub use font_set::FontSet;
use once_cell::sync::Lazy;
pub use pattern::Pattern;

pub static DATABASE: Lazy<fontdb::Database,> = Lazy::new(|| {
pub static DATABASE: Lazy<fontdb::Database> = Lazy::new(|| {
let mut db = fontdb::Database::default();
db.load_system_fonts();
return db;
},);
db
});

pub fn init() {}
6 changes: 3 additions & 3 deletions src/loader/pattern.rs
Original file line number Diff line number Diff line change
@@ -20,12 +20,12 @@ use super::Charset;

#[derive(Default)]
pub struct Pattern {
chars: Option<Charset,>,
chars: Option<Charset>,
}

impl Pattern {
pub fn add_charset(mut self, charset: Charset,) -> Self {
self.chars.replace(charset,);
pub fn add_charset(mut self, charset: Charset) -> Self {
self.chars.replace(charset);
self
}
}
32 changes: 16 additions & 16 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -36,60 +36,60 @@ fn main() {

loader::init();

let charset = loader::Charset::default().add_char(argument.char.0,);
let pattern = loader::Pattern::default().add_charset(charset,);
let font_set = loader::FontSet::match_pattern(&pattern,);
let charset = loader::Charset::default().add_char(argument.char.0);
let pattern = loader::Pattern::default().add_charset(charset);
let font_set = loader::FontSet::match_pattern(&pattern);

let families = font::SortedFamilies::from(&font_set,);
let families = font::SortedFamilies::from(&font_set);

if families.is_empty() {
println!("No font support this character.");
return;
}

if argument.tui {
let ui = UI::new(argument.char.0, families,).unwrap();
let ui = UI::new(argument.char.0, families).unwrap();
ui.show().unwrap_or_else(|err| {
eprintln!("{:?}", err);
},);
});
} else {
let builder = if argument.preview {
Some(PreviewServerBuilder::from_iter(families.iter(),),)
Some(PreviewServerBuilder::from_iter(families.iter()))
} else {
None
};

println!("Font(s) support the character {}:", argument.char.description());
show_font_list(families, argument.verbose,);
show_font_list(families, argument.verbose);

if let Some(builder,) = builder {
builder.build_for(argument.char.0,).run_until(show_preview_addr_and_wait,);
if let Some(builder) = builder {
builder.build_for(argument.char.0).run_until(show_preview_addr_and_wait);
}
}
}

fn show_preview_addr_and_wait(addr: SocketAddr,) {
fn show_preview_addr_and_wait(addr: SocketAddr) {
println!("{}", "-".repeat(40));
println!("Please visit http://{}/ in your browser for preview", addr);
print!("And press Enter after your finish...");
std::io::stdout().flush().unwrap();

// Wait until user input any character before stop the server
let mut line = " ".to_string();
std::io::stdin().read_line(&mut line,).unwrap();
std::io::stdin().read_line(&mut line).unwrap();
}

fn show_font_list(families: SortedFamilies<'_, '_,>, verbose: bool,) {
fn show_font_list(families: SortedFamilies<'_, '_>, verbose: bool) {
let max_len = if verbose {
0
} else {
families.iter().map(|f| f.default_name_width,).max().unwrap_or_default()
families.iter().map(|f| f.default_name_width).max().unwrap_or_default()
};

families.into_iter().for_each(|mut family| {
if verbose {
println!("{}", family.name);
while let Some(Reverse(face,),) = family.fonts.pop() {
while let Some(Reverse(face)) = family.fonts.pop() {
println!(" {}", face.0.name);
}
} else {
@@ -101,5 +101,5 @@ fn show_font_list(families: SortedFamilies<'_, '_,>, verbose: bool,) {
family_name_length = max_len,
);
}
},);
});
}
Loading