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

Error-handling cleanup, etc. #147

Merged
merged 3 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,22 @@ members = [
"csln",
"processor",
]

[workspace.lints.rust]
unsafe_code = "forbid"

[workspace.lints.clippy]
# not sure on what to turn on and off
complexity = "allow"
expect_used = "warn"
large_enum_variant = "allow"
needless_borrow = "warn"
needless_question_mark = "warn"
needless_return = "warn"
style = "allow"
unwrap_used = "warn"

[profile.release]
lto = true
codegen-units = 1
panic = "abort"
2 changes: 2 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ schemars = "0.8"
serde_json = "1.0"
csln = { path = "../csln", package = "csln" }
processor = { path = "../processor", package = "csln-processor" }
anyhow = "1.0.79"


35 changes: 22 additions & 13 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use anyhow::Context;
use clap::Parser;
use csln::bibliography::InputBibliography as Bibliography;
use csln::citation::Citations;
use csln::style::Style;
use csln::HasFile;
use processor::Processor;
use csln::from_file;
use processor::{ProcReferences, Processor};

#[derive(Parser, Default, Debug)]
#[clap(author = "Bruce D'Arcus", version, about = "A CLI for CSLN")]
Expand All @@ -16,24 +15,34 @@ pub struct Opts {
bibliography: String,
#[clap(short, long)]
/// The optional path to the CSLN citation file
citation: Option<String>,
citations: Option<String>,
#[clap(short, long)]
/// The path to the CSLN locale file
locale: String,
}

fn main() {
let opts = Opts::parse();
let style: Style = Style::from_file(&opts.style);
let bibliography: Bibliography = Bibliography::from_file(&opts.bibliography);
let citations: Citations = if opts.citation.is_none() {
let style = from_file(&opts.style).context("Style file?");
let bibliography = from_file(&opts.bibliography).context("Bibliography file?");
let citations: Citations = if opts.citations.is_none() {
Citations::default()
} else {
Citations::from_file(&opts.citation.unwrap_or_default())
from_file(opts.citations.unwrap()).unwrap_or_default()
};
let locale = csln::style::locale::Locale::from_file(&opts.locale);
let processor: Processor = Processor::new(style, bibliography, citations, locale);
let rendered_refs = processor.process_references();
let locale = from_file(&opts.locale).context("Locale file?");
let processor: Processor = Processor::new(
style.expect("msg"), // REVIEW why?
bibliography.expect("msg"),
citations,
locale.expect("msg"),
);
let rendered_refs: ProcReferences = processor.process_references();
let serialized_refs = serde_json::to_string_pretty(&rendered_refs);
//println!("{}", refs_to_string(rendered_refs));
println!("{}", serde_json::to_string_pretty(&rendered_refs).unwrap());
if serialized_refs.is_err() {
println!("Error: {:?}", serialized_refs);
} else {
println!("{}", serialized_refs.unwrap());
}
}
2 changes: 1 addition & 1 deletion cli/src/makeschemas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use csln::style::locale::Locale;
use csln::style::Style;

fn main() {
fs::create_dir_all("schemas").unwrap();
fs::create_dir_all("schemas").expect("Failed to create directory 'schemas'");

let style_schema = schema_for!(Style);
let citation_schema = schema_for!(CitationList);
Expand Down
4 changes: 4 additions & 0 deletions csln/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ chrono = { version = "0.4", features = ["unstable-locales"] }
unic-langid = { version = "0.9.1", features = ["serde"] }
itertools = "0.11.0"
rayon = "1.7.0"
anyhow = "1.0.79"
#icu = { version = "1.2.0", features = ["icu_datetime_experimental"] }
#icu_testdata = { version = "1.2.0", features = ["icu_datetime_experimental"] }
#indexmap = { version = "2.0.0", features = ["std"] }

[lints]
workspace = true

17 changes: 0 additions & 17 deletions csln/src/bibliography/mod.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
use crate::HasFile;
use std::collections::HashMap;
use std::fs;

pub mod reference;
pub use reference::InputReference;

/// A bibliography is a collection of references.
pub type InputBibliography = HashMap<String, InputReference>;

impl HasFile for InputBibliography {
/// Load and parse a YAML or JSON bibliography file.
fn from_file(bib_path: &str) -> InputBibliography {
let contents =
fs::read_to_string(bib_path).expect("Failed to read bibliography file");
if bib_path.ends_with(".json") {
serde_json::from_str(&contents).expect("Failed to parse JSON")
} else if bib_path.ends_with(".yaml") || bib_path.ends_with(".yml") {
serde_yaml::from_str(&contents).expect("Failed to parse YAML")
} else {
panic!("Style file must be in YAML or JSON format")
}
}
}
16 changes: 0 additions & 16 deletions csln/src/citation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
use crate::HasFile;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fs;

impl HasFile for Citations {
fn from_file(citations_path: &str) -> Citations {
let contents =
fs::read_to_string(citations_path).expect("Failed to read citations file");
if citations_path.ends_with(".json") {
serde_json::from_str(&contents).expect("Failed to parse JSON")
} else if citations_path.ends_with(".yaml") || citations_path.ends_with(".yml") {
serde_yaml::from_str(&contents).expect("Failed to parse YAML")
} else {
panic!("Citations file must be in YAML or JSON format")
}
}
}

pub type Citations = Vec<Citation>;

Expand Down
34 changes: 32 additions & 2 deletions csln/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
pub mod style;
use std::path::Path;

use serde::de::DeserializeOwned;
pub use style::Style;

use std::fs;

pub mod bibliography;
pub use bibliography::InputBibliography;
use style::locale::Locale;

use anyhow::{Context, Result};

pub mod citation;

pub trait HasFile {
fn from_file(path: &str) -> Self;
pub trait Parsable: DeserializeOwned {}
impl Parsable for Style {}
impl Parsable for Locale {}
impl Parsable for InputBibliography {}
impl Parsable for citation::Citations {}

pub fn from_file<T: Parsable, P: AsRef<Path>>(path: P) -> Result<T> {
let path = path.as_ref();
let contents = fs::read_to_string(path)
.with_context(|| format!("Failed to read file: {}", path.display()))?;

let value = if path.extension().and_then(|s| s.to_str()) == Some("json") {
serde_json::from_str(&contents).with_context(|| {
format!("Failed to parse JSON from file: {}", path.display())
})?
} else if path.extension().and_then(|s| s.to_str()) == Some("yaml") {
serde_yaml::from_str(&contents).with_context(|| {
format!("Failed to parse YAML from file: {}", path.display())
})?
} else {
return Err(anyhow::anyhow!("Unsupported file extension"));
};

Ok(value)
}
16 changes: 1 addition & 15 deletions csln/src/style/locale.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fs};
use std::collections::HashMap;
//use unic_langid::LanguageIdentifier;

#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonSchema)]
Expand Down Expand Up @@ -30,20 +30,6 @@ pub struct Terms {
pub ibid: Option<String>,
}

impl Locale {
pub fn from_file(locale_path: &str) -> Locale {
let contents =
fs::read_to_string(locale_path).expect("Failed to read locale file");
if locale_path.ends_with(".json") {
serde_json::from_str(&contents).expect("Failed to parse JSON")
} else if locale_path.ends_with(".yaml") || locale_path.ends_with(".yml") {
serde_yaml::from_str(&contents).expect("Failed to parse YAML")
} else {
panic!("Locale file must be in YAML or JSON format")
}
}
}

#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonSchema)]
pub struct AndAs {
pub symbol: String,
Expand Down
15 changes: 0 additions & 15 deletions csln/src/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ SPDX-FileCopyrightText: © 2023 Bruce D'Arcus
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;

pub mod locale;
pub mod options;
Expand All @@ -15,20 +14,6 @@ use options::Config;
pub mod template;
use template::TemplateComponent;

impl Style {
/// Load and parse a YAML or JSON style file.
pub fn from_file(style_path: &str) -> Style {
let contents = fs::read_to_string(style_path).expect("Failed to read style file");
if style_path.ends_with(".json") {
serde_json::from_str(&contents).expect("Failed to parse JSON")
} else if style_path.ends_with(".yaml") || style_path.ends_with(".yml") {
serde_yaml::from_str(&contents).expect("Failed to parse YAML")
} else {
panic!("Style file must be in YAML or JSON format")
}
}
}

/// The Style model.
#[derive(Debug, Default, Deserialize, Serialize, Clone, JsonSchema)]
pub struct Style {
Expand Down
2 changes: 1 addition & 1 deletion csln/src/style/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn author_date_config() {
let sort = config.sort.unwrap_or_default();
assert_eq!(sort.template[0].key, SortKey::Author);
assert_eq!(sort.template[1].key, SortKey::Year);
assert!(config.disambiguate.unwrap().year_suffix);
assert!(config.disambiguate.unwrap_or_default().year_suffix);
}

#[derive(JsonSchema, Debug, PartialEq, Clone, Serialize, Deserialize)]
Expand Down
3 changes: 3 additions & 0 deletions processor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ criterion = { version = "0.5.1", features = ["html_reports"] }
[[bench]]
name = "proc_bench"
harness = false

[lints]
workspace = true
18 changes: 12 additions & 6 deletions processor/benches/proc_bench.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
use criterion::{criterion_group, criterion_main, Criterion};
use csln::bibliography::InputBibliography as Bibliography;
use csln::citation::Citation;
use csln::style::Style;
use csln::HasFile;
use csln::from_file;
use csln_processor::Processor;
use std::time::Duration;

fn proc_benchmark(c: &mut Criterion) {
let style: Style = Style::from_file("examples/style.csl.yaml");
let bibliography: Bibliography = Bibliography::from_file("examples/ex1.bib.yaml");
let locale = csln::style::locale::Locale::from_file("locales/locale-en.yaml");
let style = match from_file("examples/style.csl.yaml") {
Ok(style) => style,
Err(_) => {
println!("Failed to load style");
return;
}
};
let bibliography: Bibliography = from_file("examples/ex1.bib.yaml").expect("msg");
let locale = from_file("locales/locale-en.yaml");
let citations: Vec<Citation> = Vec::new();
let processor: Processor = Processor::new(style, bibliography, citations, locale);
let processor: Processor =
Processor::new(style, bibliography, citations, locale.expect("msg"));
c.bench_function("sorting references", |b| {
b.iter(|| {
let refs = processor.get_references();
Expand Down
Loading
Loading