1pub mod arxiv;
2pub mod biorxiv;
3pub mod core;
4pub mod crossref;
5pub mod dblp;
6pub mod doaj;
7pub mod europepmc;
8pub mod hal;
9pub mod medrxiv;
10pub mod openaire;
11pub mod openalex;
12pub mod pmc;
13pub mod pubmed;
14pub mod scholar;
15pub mod semantic;
16pub mod unpaywall;
17pub mod zenodo;
18
19use serde::Serialize;
20
21pub fn encode_query(query: &str) -> String {
23 let mut encoded = String::with_capacity(query.len() * 3);
24 for byte in query.bytes() {
25 match byte {
26 b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
27 encoded.push(byte as char);
28 }
29 b' ' => encoded.push('+'),
30 _ => {
31 encoded.push('%');
32 encoded.push_str(&format!("{:02X}", byte));
33 }
34 }
35 }
36 encoded
37}
38
39#[derive(Debug, Clone, Serialize)]
41pub struct Paper {
42 pub id: String,
43 pub title: String,
44 pub authors: Vec<String>,
45 #[serde(rename = "abstract")]
46 pub abstract_text: Option<String>,
47 pub year: Option<u16>,
48 pub doi: Option<String>,
49 pub url: Option<String>,
50 pub pdf_url: Option<String>,
51 pub venue: Option<String>,
52 pub citations: Option<u32>,
53 pub fields: Vec<String>,
54 pub open_access: Option<bool>,
55 pub source: String,
56}