# Rust quickstart This is a ~60-second round-trip: snapshot a directory, `push` it to a local `file://` store, `pull` it back into a fresh directory, and confirm the snapshot ID matches. Snapshot IDs are 64-character lowercase hex and are bit-identical to the CLI and every other binding. ## 1. Install ```sh cargo add snapdir-api cargo add tokio --features full ``` `snapdir-api` is a native crate — `cargo` builds it from source, no C toolchain required. See [Install snapdir for Rust](/install/rust/) for platform details. ## 2. Snapshot + push Compute the snapshot ID for a directory, then push it to a local store. Both calls return the same 64-character lowercase hex ID. The store URI is always an argument — `file://$PWD/store` is a no-setup local store. ```rust use snapdir_api::{id, push, ManifestOptions, PushSource, StoreUri, TransferOptions}; use std::path::Path; #[tokio::main] async fn main() -> Result<(), Box> { let store = StoreUri::parse(&format!( "file://{}/store", std::env::current_dir()?.display() ))?; // Snapshot ID — pure and deterministic, no store touched. let snapshot_id = id(Path::new("./my-dir"), &ManifestOptions::default())?; println!("{}", snapshot_id.to_hex()); // 64-char lowercase hex // Upload the snapshot to the store; returns the same ID. let pushed = push( PushSource::Path(Path::new("./my-dir")), &store, &TransferOptions::default(), ) .await?; assert_eq!(pushed, snapshot_id); Ok(()) } ``` ## 3. Pull it back Materialize the snapshot into a fresh directory and re-derive its ID — it is the same value you started with. ```rust use snapdir_api::{id, pull, CheckoutOptions, ManifestOptions}; use std::path::Path; pull( &snapshot_id, &store, Path::new("./restored"), &CheckoutOptions::default(), ) .await?; let restored = id(Path::new("./restored"), &ManifestOptions::default())?; assert_eq!(restored, snapshot_id); ``` That `` is the exact same value you would get from `snapdir id` or `snapdir push` on the CLI — the binding wraps the identical Rust core.