Skip to main content

tango/models/
protest.rs

1//! `ProtestRecord` — typed response from `GET /api/protests/{case_id}/`.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::collections::HashMap;
6
7/// A bid-protest case record.
8///
9/// Returned by [`Client::get_protest`](crate::Client::get_protest). Fields
10/// match the server's shape preset for the detail endpoint; unknown fields
11/// fall through to [`extra`](Self::extra).
12#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
13pub struct ProtestRecord {
14    /// Internal Tango identifier for the case.
15    #[serde(default, skip_serializing_if = "Option::is_none")]
16    pub case_id: Option<String>,
17
18    /// Source-system case number (e.g. GAO file number).
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub case_number: Option<String>,
21
22    /// Human-readable title.
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub title: Option<String>,
25
26    /// Source system (`"GAO"`, `"COFC"`, etc.).
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub source_system: Option<String>,
29
30    /// Outcome label (`"sustained"`, `"denied"`, …).
31    #[serde(default, skip_serializing_if = "Option::is_none")]
32    pub outcome: Option<String>,
33
34    /// ISO date the protest was filed.
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub filed_date: Option<String>,
37
38    /// ISO date the protest was decided, when present.
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub decision_date: Option<String>,
41
42    /// Forward-compatible bucket for any unrecognized fields the server adds.
43    #[serde(flatten)]
44    pub extra: HashMap<String, Value>,
45}