xref: /third_party/rust/crates/cxx/demo/src/main.rs (revision 33d722a9)
1#[cxx::bridge(namespace = "org::blobstore")]
2mod ffi {
3    // Shared structs with fields visible to both languages.
4    struct BlobMetadata {
5        size: usize,
6        tags: Vec<String>,
7    }
8
9    // Rust types and signatures exposed to C++.
10    extern "Rust" {
11        type MultiBuf;
12
13        fn next_chunk(buf: &mut MultiBuf) -> &[u8];
14    }
15
16    // C++ types and signatures exposed to Rust.
17    unsafe extern "C++" {
18        include!("demo/include/blobstore.h");
19
20        type BlobstoreClient;
21
22        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
23        fn put(&self, parts: &mut MultiBuf) -> u64;
24        fn tag(&self, blobid: u64, tag: &str);
25        fn metadata(&self, blobid: u64) -> BlobMetadata;
26    }
27}
28
29// An iterator over contiguous chunks of a discontiguous file object.
30//
31// Toy implementation uses a Vec<Vec<u8>> but in reality this might be iterating
32// over some more complex Rust data structure like a rope, or maybe loading
33// chunks lazily from somewhere.
34pub struct MultiBuf {
35    chunks: Vec<Vec<u8>>,
36    pos: usize,
37}
38pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {
39    let next = buf.chunks.get(buf.pos);
40    buf.pos += 1;
41    next.map_or(&[], Vec::as_slice)
42}
43
44fn main() {
45    let client = ffi::new_blobstore_client();
46
47    // Upload a blob.
48    let chunks = vec![b"fearless".to_vec(), b"concurrency".to_vec()];
49    let mut buf = MultiBuf { chunks, pos: 0 };
50    let blobid = client.put(&mut buf);
51    println!("blobid = {}", blobid);
52
53    // Add a tag.
54    client.tag(blobid, "rust");
55
56    // Read back the tags.
57    let metadata = client.metadata(blobid);
58    println!("tags = {:?}", metadata.tags);
59}
60