use uuid::Uuid;
use crate::api::ControlPlaneClient;
use crate::config::SessionConfig;
#[derive(serde::Deserialize)]
struct CharacterList {
characters: Vec<CharacterRow>,
}
#[derive(serde::Deserialize)]
struct CharacterRow {
id: Uuid,
#[serde(rename = "name")]
_name: String,
}
#[derive(Debug, serde::Serialize)]
pub struct InventoryOutput {
pub character_id: Uuid,
pub items: Vec<InventoryItem>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct InventoryItem {
pub item_instance_id: Uuid,
pub template_id: String,
pub quantity: i32,
}
pub async fn run(character_id: Option<Uuid>, json: bool) -> anyhow::Result<()> {
let session = SessionConfig::load()?;
let client = ControlPlaneClient::new(&session.api_base);
let character_id = match character_id {
Some(id) => id,
None => {
let list: CharacterList = client
.get("/v1/characters", &session.session_token)
.await?;
list.characters
.first()
.map(|c| c.id)
.ok_or_else(|| {
anyhow::anyhow!("no characters — run flatland3 auth register")
})?
}
};
#[derive(serde::Deserialize)]
struct InventoryResponse {
character_id: Uuid,
items: Vec<InventoryItem>,
}
let inv: InventoryResponse = client
.get(
&format!("/v1/characters/{character_id}/inventory"),
&session.session_token,
)
.await?;
let output = InventoryOutput {
character_id: inv.character_id,
items: inv.items,
};
if json {
println!(
"{}",
serde_json::to_string_pretty(&serde_json::json!({
"ok": true,
"data": output
}))?
);
} else if output.items.is_empty() {
println!("Inventory empty for character {}", output.character_id);
} else {
println!("Inventory for {}:", output.character_id);
for item in &output.items {
println!(
" {} x{} ({})",
item.template_id, item.quantity, item.item_instance_id
);
}
}
Ok(())
}