| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 1 | #[cxx::bridge(namespace = "org::blobstore")] |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 2 | mod ffi { |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 3 | // Shared structs with fields visible to both languages. |
| 4 | struct BlobMetadata { |
| 5 | size: usize, |
| 6 | tags: Vec<String>, |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 7 | } |
| 8 | |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 9 | // Rust types and signatures exposed to C++. |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 10 | extern "Rust" { |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 11 | type MultiBuf; |
| 12 | |
| 13 | fn next_chunk(buf: &mut MultiBuf) -> &[u8]; |
| 14 | } |
| 15 | |
| 16 | // C++ types and signatures exposed to Rust. |
| David Tolnay | 7be5b1f | 2020-11-11 10:48:32 -0800 | [diff] [blame] | 17 | unsafe extern "C++" { |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 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; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 26 | } |
| 27 | } |
| 28 | |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 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. |
| 34 | pub struct MultiBuf { |
| 35 | chunks: Vec<Vec<u8>>, |
| 36 | pos: usize, |
| 37 | } |
| 38 | pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] { |
| 39 | let next = buf.chunks.get(buf.pos); |
| 40 | buf.pos += 1; |
| 41 | next.map(Vec::as_slice).unwrap_or(&[]) |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | fn main() { |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 45 | let client = ffi::new_blobstore_client(); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 46 | |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 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); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 59 | } |