#[cxx::bridge(namespace = "org::blobstore")] mod ffi { // Shared structs with fields visible to both languages. struct BlobMetadata { size: usize, tags: Vec, } // Rust types and signatures exposed to C++. extern "Rust" { type MultiBuf; fn next_chunk(buf: &mut MultiBuf) -> &[u8]; } // C++ types and signatures exposed to Rust. unsafe extern "C++" { include!("demo/include/blobstore.h"); type BlobstoreClient; fn new_blobstore_client() -> UniquePtr; fn put(&self, parts: &mut MultiBuf) -> u64; fn tag(&self, blobid: u64, tag: &str); fn metadata(&self, blobid: u64) -> BlobMetadata; } } // An iterator over contiguous chunks of a discontiguous file object. // // Toy implementation uses a Vec> but in reality this might be iterating // over some more complex Rust data structure like a rope, or maybe loading // chunks lazily from somewhere. pub struct MultiBuf { chunks: Vec>, pos: usize, } pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] { let next = buf.chunks.get(buf.pos); buf.pos += 1; next.map_or(&[], Vec::as_slice) } fn main() { let client = ffi::new_blobstore_client(); // Upload a blob. let chunks = vec![b"fearless".to_vec(), b"concurrency".to_vec()]; let mut buf = MultiBuf { chunks, pos: 0 }; let blobid = client.put(&mut buf); println!("blobid = {}", blobid); // Add a tag. client.tag(blobid, "rust"); // Read back the tags. let metadata = client.metadata(blobid); println!("tags = {:?}", metadata.tags); }