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 xueshu;
18pub mod zenodo;
19
20use serde::Serialize;
21
22pub fn encode_query(query: &str) -> String {
24 let mut encoded = String::with_capacity(query.len() * 3);
25 for byte in query.bytes() {
26 match byte {
27 b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
28 encoded.push(byte as char);
29 }
30 b' ' => encoded.push('+'),
31 _ => {
32 encoded.push('%');
33 encoded.push_str(&format!("{:02X}", byte));
34 }
35 }
36 }
37 encoded
38}
39
40#[derive(Debug, Clone, Serialize)]
42pub struct Paper {
43 pub id: String,
44 pub title: String,
45 pub authors: Vec<String>,
46 #[serde(rename = "abstract")]
47 pub abstract_text: Option<String>,
48 pub year: Option<u16>,
49 pub doi: Option<String>,
50 pub url: Option<String>,
51 pub pdf_url: Option<String>,
52 pub venue: Option<String>,
53 pub citations: Option<u32>,
54 pub fields: Vec<String>,
55 pub open_access: Option<bool>,
56 pub source: String,
57}