#[cfg(feature = "polars")]
mod analytics;
#[allow(clippy::module_inception)]
mod check;
mod consistency;
pub mod discrepancy;
mod error;
mod integrity;
mod preprocess;
mod synchrony;
mod translate;
pub mod utils;
use crate::check::check::check_common;
pub use crate::check::check::ProofCheck;
#[cfg(not(feature = "wasm"))]
use crate::check::error::ProofModeError;
#[cfg(feature = "wasm")]
use crate::check::utils::translate_from_js_files;
#[cfg(not(feature = "wasm"))]
use crate::check::utils::ReporterCallback;
use crate::check::utils::{fetch_url, ProgressReporter};
#[cfg(feature = "wasm")]
use js_sys::Function;
#[cfg(feature = "wasm")]
use serde::Serialize;
#[cfg(feature = "wasm")]
use serde_wasm_bindgen::Serializer;
#[cfg(not(feature = "wasm"))]
use std::fs::File;
#[cfg(not(feature = "wasm"))]
use std::io::Cursor;
#[cfg(not(feature = "wasm"))]
use std::io::Read;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
#[cfg(feature = "wasm")]
use wasm_bindgen::JsValue;
#[cfg(feature = "wasm")]
#[wasm_bindgen(js_name = "checkFiles")]
pub async fn check_files(files: JsValue, send_message: &Function) -> Result<JsValue, JsValue> {
let web_files = translate_from_js_files(files);
let progress = ProgressReporter::new(send_message.clone());
let proof_check = check_common(web_files, &progress);
let serializer = Serializer::new()
.serialize_maps_as_objects(true)
.serialize_bytes_as_arrays(false);
match proof_check.serialize(&serializer) {
Ok(json) => Ok(json),
Err(e) => Err(JsValue::from_str(&format!(
"Failed to serialize proof check: {}",
e
))),
}
}
#[cfg(not(feature = "wasm"))]
pub fn check_files(
files: &[String],
send_message: ReporterCallback,
) -> Result<ProofCheck, ProofModeError> {
let input_files = files
.iter()
.map(|path| match File::open(path) {
Ok(mut file) => {
let mut contents = Vec::new();
match file.read_to_end(&mut contents) {
Ok(_) => {
let cursor = Cursor::new(contents);
preprocess::LocalFile {
name: path.clone(),
error: None,
data: cursor,
}
}
Err(e) => preprocess::LocalFile {
name: path.clone(),
error: Some(format!("Could not read file: {}", e)),
data: Cursor::new(Vec::new()),
},
}
}
Err(e) => preprocess::LocalFile {
name: path.clone(),
error: Some(format!("Could not open file: {}", e)),
data: Cursor::new(Vec::new()),
},
})
.collect();
let progress = ProgressReporter::new(send_message);
let proof_check = check_common(input_files, &progress);
Ok(proof_check)
}
#[cfg(feature = "wasm")]
#[wasm_bindgen(js_name = "checkURLs")]
pub async fn check_urls(urls: JsValue, send_message: &Function) -> Result<JsValue, JsValue> {
let urls_array: js_sys::Array = urls.into();
let mut fetch_files = Vec::new();
for i in 0..urls_array.length() {
match urls_array.get(i).as_string() {
Some(url) => match fetch_url(&url).await {
Ok(res) => fetch_files.push(res),
Err(e) => {
let error_msg = format!("Failed to fetch URL {}: {:?}", url, e);
return Err(JsValue::from_str(&error_msg));
}
},
None => {
return Err(JsValue::from_str("Invalid URL in array"));
}
}
}
let progress = ProgressReporter::new(send_message.clone());
let proof_check = check_common(fetch_files, &progress);
let serializer = Serializer::new()
.serialize_maps_as_objects(true)
.serialize_bytes_as_arrays(false);
match proof_check.serialize(&serializer) {
Ok(json) => Ok(json),
Err(e) => Err(JsValue::from_str(&format!(
"Failed to serialize proof check: {}",
e
))),
}
}
#[cfg(not(feature = "wasm"))]
pub fn check_urls(
urls: &[String],
send_message: ReporterCallback,
) -> Result<ProofCheck, ProofModeError> {
let mut fetch_files = Vec::new();
for i in 0..urls.len() {
let url = urls.get(i).ok_or_else(|| ProofModeError::Failure {
message: "Invalid URL index".to_string(),
})?;
let res = fetch_url(url)?;
fetch_files.push(res);
}
let progress = ProgressReporter::new(send_message);
let proof_check = check_common(fetch_files, &progress);
Ok(proof_check)
}
#[cfg(feature = "wasm")]
#[wasm_bindgen(js_name = "checkCIDs")]
pub async fn check_cids(cids: JsValue, send_message: &Function) -> Result<JsValue, JsValue> {
let cids_array: js_sys::Array = cids.into();
let urls_array = js_sys::Array::new();
for i in 0..cids_array.length() {
match cids_array.get(i).as_string() {
Some(cid) => {
let url = format!("https://cloudflare-ipfs.com/ipfs/{}", cid);
urls_array.push(&JsValue::from_str(url.as_str()));
}
None => {
return Err(JsValue::from_str("Invalid CID in array"));
}
}
}
check_urls(urls_array.into(), send_message).await
}
#[cfg(not(feature = "wasm"))]
pub fn check_cids(
cids: &Vec<String>,
send_message: ReporterCallback,
) -> Result<ProofCheck, ProofModeError> {
let mut urls = Vec::new();
for cid in cids {
let url = format!("https://cloudflare-ipfs.com/ipfs/{}", cid);
urls.push(url);
}
check_urls(&urls, send_message)
}