# Worked examples

All examples assume `ZOO_API_TOKEN` is exported and these dependencies:

```toml
[dependencies]
kittycad = "0.5.7"
tokio = { version = "1", features = ["rt", "macros"] }
anyhow = "1"
bytes = "1"
futures-util = "0.3"
```

## 1. Convert a CAD file (STEP → STL)

```rust,no_run
use kittycad::types::{FileExportFormat, FileImportFormat};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = kittycad::Client::new_from_env();
    let input = std::fs::read("part.step")?;

    let result = client
        .file()
        .create_conversion(
            FileExportFormat::Stl,
            FileImportFormat::Step,
            &bytes::Bytes::from(input),
        )
        .await?;

    println!("{:?}", result.status);
    Ok(())
}
```

The same module also computes geometry properties of an uploaded file:
`create_volume`, `create_mass`, `create_density`, `create_surface_area`,
`create_center_of_mass`, `create_bounding_box`.

## 2. Convert units

Server-side unit conversion across length, mass, force, pressure, torque,
temperature, and more:

```rust,no_run
use kittycad::types::UnitLength;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = kittycad::Client::new_from_env();

    let conv = client
        .unit()
        .get_length_conversion(UnitLength::In, UnitLength::Mm, 2.5)
        .await?;

    println!("2.5 in = {:?} mm", conv.output);
    Ok(())
}
```

## 3. Inspect your account and API usage

```rust,no_run
#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = kittycad::Client::new_from_env();

    let me = client.users().get_self().await?;
    println!("me: {:?}", me);
    Ok(())
}
```

`client.api_calls()` exposes your recent API calls — useful for debugging
and for understanding billing.

## 4. Paginate with streams

Every list endpoint has a `*_stream` twin that handles page tokens for you
and yields items as a `futures::Stream`. For example, listing your
text-to-CAD generations:

```rust,no_run
use futures_util::TryStreamExt;
use kittycad::ml::ListTextToCadPartsForUserParams;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = kittycad::Client::new_from_env();
    let mut ml = client.ml();

    let mut stream = ml.list_text_to_cad_parts_for_user_stream(
        ListTextToCadPartsForUserParams {
            conversation_id: None,
            limit: None,
            no_models: None,
            no_parts: Some(true),   // metadata only
            page_token: None,
            sort_by: None,
        },
    );

    while let Some(part) = stream.try_next().await? {
        println!("{:?}", part);
    }
    Ok(())
}
```

## 5. Handling errors

Every call returns `Result<T, kittycad::types::error::Error>`. Server-side
failures carry the status and raw body:

```rust,no_run
use kittycad::types::error::Error;

#[tokio::main]
async fn main() {
    let client = kittycad::Client::new_from_env();
    match client.users().get_self().await {
        Ok(me) => println!("ok: {:?}", me),
        Err(Error::Server { status, body }) => {
            eprintln!("API error {}: {}", status, body);
        }
        Err(other) => eprintln!("client-side error: {}", other),
    }
}
```

Transient network failures are retried automatically with backoff
(`reqwest-retry` under the hood), so you generally only see errors that are
worth surfacing.
