mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-26 09:05:50 +00:00
161 lines
4.5 KiB
Rust
161 lines
4.5 KiB
Rust
extern crate cbindgen;
|
|
|
|
use std::env;
|
|
use std::fs::{remove_file, File};
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
|
|
const TEMPLATE_EACH: &'static str = r#"
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_list(
|
|
storage: *mut {path},
|
|
err: *mut VdirsyncerError
|
|
) -> *mut VdirsyncerStorageListing {
|
|
match (*storage).list() {
|
|
Ok(x) => Box::into_raw(Box::new(VdirsyncerStorageListing {
|
|
iterator: x,
|
|
href: None,
|
|
etag: None
|
|
})),
|
|
Err(e) => {
|
|
e.fill_c_err(err);
|
|
mem::zeroed()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_get(
|
|
storage: *mut {path},
|
|
c_href: *const c_char,
|
|
err: *mut VdirsyncerError
|
|
) -> *mut VdirsyncerStorageGetResult {
|
|
let href = CStr::from_ptr(c_href);
|
|
match (*storage).get(href.to_str().unwrap()) {
|
|
Ok((item, href)) => {
|
|
Box::into_raw(Box::new(VdirsyncerStorageGetResult {
|
|
item: Box::into_raw(Box::new(item)),
|
|
etag: CString::new(href).unwrap().into_raw()
|
|
}))
|
|
},
|
|
Err(e) => {
|
|
e.fill_c_err(err);
|
|
mem::zeroed()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_upload(
|
|
storage: *mut {path},
|
|
item: *mut Item,
|
|
err: *mut VdirsyncerError
|
|
) -> *mut VdirsyncerStorageUploadResult {
|
|
match (*storage).upload((*item).clone()) {
|
|
Ok((href, etag)) => {
|
|
Box::into_raw(Box::new(VdirsyncerStorageUploadResult {
|
|
href: CString::new(href).unwrap().into_raw(),
|
|
etag: CString::new(etag).unwrap().into_raw()
|
|
}))
|
|
},
|
|
Err(e) => {
|
|
e.fill_c_err(err);
|
|
mem::zeroed()
|
|
}
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_update(
|
|
storage: *mut {path},
|
|
c_href: *const c_char,
|
|
item: *mut Item,
|
|
c_etag: *const c_char,
|
|
err: *mut VdirsyncerError
|
|
) -> *const c_char {
|
|
let href = CStr::from_ptr(c_href);
|
|
let etag = CStr::from_ptr(c_etag);
|
|
match (*storage).update(href.to_str().unwrap(), (*item).clone(), etag.to_str().unwrap()) {
|
|
Ok(etag) => CString::new(etag).unwrap().into_raw(),
|
|
Err(e) => {
|
|
e.fill_c_err(err);
|
|
mem::zeroed()
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_delete(
|
|
storage: *mut {path},
|
|
c_href: *const c_char,
|
|
c_etag: *const c_char,
|
|
err: *mut VdirsyncerError
|
|
) {
|
|
let href = CStr::from_ptr(c_href);
|
|
let etag = CStr::from_ptr(c_etag);
|
|
match (*storage).delete(href.to_str().unwrap(), etag.to_str().unwrap()) {
|
|
Ok(()) => (),
|
|
Err(e) => e.fill_c_err(err)
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_buffered(storage: *mut {path}) {
|
|
(*storage).buffered();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn vdirsyncer_{name}_flush(
|
|
storage: *mut {path},
|
|
err: *mut VdirsyncerError
|
|
) {
|
|
match (*storage).flush() {
|
|
Ok(_) => (),
|
|
Err(e) => e.fill_c_err(err)
|
|
}
|
|
}
|
|
"#;
|
|
|
|
fn export_storage(f: &mut File, name: &str, path: &str) {
|
|
// String formatting in rust is at compile time. That doesn't work well for our case.
|
|
write!(
|
|
f,
|
|
"{}",
|
|
TEMPLATE_EACH
|
|
.replace("{name}", name)
|
|
.replace("{path}", path)
|
|
).unwrap();
|
|
}
|
|
|
|
fn main() {
|
|
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
|
|
|
let mut f = File::create(Path::new(&crate_dir).join("src/storage/exports.rs")).unwrap();
|
|
write!(f, "// Auto-generated, do not check in.\n").unwrap();
|
|
write!(f, "use std::os::raw::c_char;\n").unwrap();
|
|
write!(f, "use std::mem;\n").unwrap();
|
|
write!(f, "use std::ffi::{{CStr, CString}};\n").unwrap();
|
|
write!(f, "use errors::*;\n").unwrap();
|
|
write!(f, "use item::Item;\n").unwrap();
|
|
write!(f, "use super::VdirsyncerStorageListing;\n").unwrap();
|
|
write!(f, "use super::VdirsyncerStorageGetResult;\n").unwrap();
|
|
write!(f, "use super::VdirsyncerStorageUploadResult;\n").unwrap();
|
|
write!(f, "use super::Storage;\n").unwrap();
|
|
|
|
write!(f, "use super::singlefile;\n").unwrap();
|
|
export_storage(&mut f, "singlefile", "singlefile::SinglefileStorage");
|
|
drop(f);
|
|
|
|
let _ = remove_file(Path::new(&crate_dir).join("target/vdirsyncer_rustext.h"));
|
|
|
|
let res = cbindgen::Builder::new()
|
|
.with_crate(crate_dir)
|
|
.with_language(cbindgen::Language::C)
|
|
.generate();
|
|
|
|
match res {
|
|
Ok(x) => x.write_to_file("target/vdirsyncer_rustext.h"),
|
|
Err(e) => println!("FAILED TO GENERATE BINDINGS: {:?}", e),
|
|
}
|
|
}
|