use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use super::common::{DateTimeString, UriString};
fn nullable_f32<'de, D: Deserializer<'de>>(de: D) -> Result<f32, D::Error> {
Option::<f32>::deserialize(de).map(|o| o.unwrap_or(0.0))
}
fn string_or_int<'de, D: Deserializer<'de>>(de: D) -> Result<Option<String>, D::Error> {
let v = Option::<Value>::deserialize(de)?;
match v {
None | Some(Value::Null) => Ok(None),
Some(Value::String(s)) if s.is_empty() => Ok(None),
Some(Value::String(s)) => Ok(Some(s)),
Some(Value::Number(n)) => {
if n.as_f64() == Some(0.0) {
Ok(None)
} else {
Ok(Some(n.to_string()))
}
}
Some(other) => Ok(Some(other.to_string())),
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct Item {
pub id: String,
pub name: String,
pub description: String,
pub item_type: String,
pub loadout_slots: Vec<String>,
pub icon: UriString,
pub rarity: String,
pub value: i32,
pub workbench: Option<String>,
pub stat_block: StatBlock,
pub flavor_text: Option<String>,
pub subcategory: Option<String>,
pub created_at: DateTimeString,
pub updated_at: DateTimeString,
pub shield_type: Option<String>,
pub loot_area: Option<String>,
pub sources: Option<Value>,
pub ammo_type: Option<String>,
pub locations: Vec<Value>,
pub guide_links: Vec<Value>,
#[serde(default)]
pub article: Option<Value>,
#[serde(default)]
pub guide_url: Option<String>,
#[serde(default)]
pub game_asset_id: Option<i64>,
#[serde(default)]
pub components: Vec<Value>,
#[serde(default)]
pub used_in: Vec<Value>,
#[serde(default)]
pub recycle_components: Vec<Value>,
#[serde(default)]
pub recycle_from: Vec<Value>,
#[serde(default)]
pub mods: Vec<Value>,
#[serde(default)]
pub dropped_by: Vec<Value>,
#[serde(default)]
pub sold_by: Vec<SoldBy>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SoldBy {
pub price: i32,
pub trader_name: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct StatBlock {
#[serde(deserialize_with = "nullable_f32")]
pub range: f32,
pub value: Option<f32>,
#[serde(deserialize_with = "nullable_f32")]
pub damage: f32,
#[serde(deserialize_with = "nullable_f32")]
pub health: f32,
#[serde(deserialize_with = "nullable_f32")]
pub radius: f32,
#[serde(deserialize_with = "nullable_f32")]
pub shield: f32,
#[serde(deserialize_with = "nullable_f32")]
pub weight: f32,
#[serde(deserialize_with = "nullable_f32")]
pub agility: f32,
#[serde(rename = "arcStun", deserialize_with = "nullable_f32")]
pub arc_stun: f32,
#[serde(deserialize_with = "nullable_f32")]
pub healing: f32,
#[serde(deserialize_with = "nullable_f32")]
pub stamina: f32,
#[serde(deserialize_with = "nullable_f32")]
pub stealth: f32,
#[serde(rename = "useTime", deserialize_with = "nullable_f32")]
pub use_time: f32,
#[serde(deserialize_with = "nullable_f32")]
pub duration: f32,
#[serde(rename = "fireRate", deserialize_with = "nullable_f32")]
pub fire_rate: f32,
#[serde(deserialize_with = "nullable_f32")]
pub stability: f32,
#[serde(rename = "stackSize", deserialize_with = "nullable_f32")]
pub stack_size: f32,
#[serde(rename = "damageMult", deserialize_with = "nullable_f32")]
pub damage_mult: f32,
#[serde(rename = "raiderStun", deserialize_with = "nullable_f32")]
pub raider_stun: f32,
#[serde(rename = "weightLimit", deserialize_with = "nullable_f32")]
pub weight_limit: f32,
#[serde(rename = "augmentSlots", deserialize_with = "nullable_f32")]
pub augment_slots: f32,
#[serde(rename = "healingSlots", deserialize_with = "nullable_f32")]
pub healing_slots: f32,
#[serde(rename = "magazineSize", deserialize_with = "nullable_f32")]
pub magazine_size: f32,
#[serde(rename = "reducedNoise", deserialize_with = "nullable_f32")]
pub reduced_noise: f32,
#[serde(rename = "shieldCharge", deserialize_with = "nullable_f32")]
pub shield_charge: f32,
#[serde(rename = "backpackSlots", deserialize_with = "nullable_f32")]
pub backpack_slots: f32,
#[serde(rename = "quickUseSlots", deserialize_with = "nullable_f32")]
pub quick_use_slots: f32,
#[serde(rename = "damagePerSecond", deserialize_with = "nullable_f32")]
pub damage_per_second: f32,
#[serde(rename = "movementPenalty", deserialize_with = "nullable_f32")]
pub movement_penalty: f32,
#[serde(rename = "safePocketSlots", deserialize_with = "nullable_f32")]
pub safe_pocket_slots: f32,
#[serde(rename = "damageMitigation", deserialize_with = "nullable_f32")]
pub damage_mitigation: f32,
#[serde(rename = "healingPerSecond", deserialize_with = "nullable_f32")]
pub healing_per_second: f32,
#[serde(rename = "reducedEquipTime", deserialize_with = "nullable_f32")]
pub reduced_equip_time: f32,
#[serde(rename = "staminaPerSecond", deserialize_with = "nullable_f32")]
pub stamina_per_second: f32,
#[serde(rename = "increasedADSSpeed", deserialize_with = "nullable_f32")]
pub increased_ads_speed: f32,
#[serde(rename = "increasedFireRate", deserialize_with = "nullable_f32")]
pub increased_fire_rate: f32,
#[serde(rename = "reducedReloadTime", deserialize_with = "nullable_f32")]
pub reduced_reload_time: f32,
#[serde(rename = "illuminationRadius", deserialize_with = "nullable_f32")]
pub illumination_radius: f32,
#[serde(rename = "increasedEquipTime", deserialize_with = "nullable_f32")]
pub increased_equip_time: f32,
#[serde(rename = "reducedUnequipTime", deserialize_with = "nullable_f32")]
pub reduced_unequip_time: f32,
#[serde(default, rename = "shieldCompatibility", deserialize_with = "string_or_int")]
pub shield_compatibility: Option<String>,
#[serde(default, rename = "compatibleWeapons", deserialize_with = "string_or_int")]
pub compatible_weapons: Option<String>,
#[serde(rename = "increasedUnequipTime", deserialize_with = "nullable_f32")]
pub increased_unequip_time: f32,
#[serde(rename = "reducedVerticalRecoil", deserialize_with = "nullable_f32")]
pub reduced_vertical_recoil: f32,
#[serde(rename = "increasedBulletVelocity", deserialize_with = "nullable_f32")]
pub increased_bullet_velocity: f32,
#[serde(rename = "increasedVerticalRecoil", deserialize_with = "nullable_f32")]
pub increased_vertical_recoil: f32,
#[serde(rename = "reducedMaxShotDispersion", deserialize_with = "nullable_f32")]
pub reduced_max_shot_dispersion: f32,
#[serde(rename = "reducedPerShotDispersion", deserialize_with = "nullable_f32")]
pub reduced_per_shot_dispersion: f32,
#[serde(rename = "reducedDurabilityBurnRate", deserialize_with = "nullable_f32")]
pub reduced_durability_burn_rate: f32,
#[serde(rename = "reducedRecoilRecoveryTime", deserialize_with = "nullable_f32")]
pub reduced_recoil_recovery_time: f32,
#[serde(rename = "increasedRecoilRecoveryTime", deserialize_with = "nullable_f32")]
pub increased_recoil_recovery_time: f32,
#[serde(rename = "reducedDispersionRecoveryTime", deserialize_with = "nullable_f32")]
pub reduced_dispersion_recovery_time: f32,
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}