use serde::Serialize;
use serde_json::Value;
use crate::capabilities::Capabilities;
use crate::changes::ChangeBurst;
use crate::diagnostics::DiagnosticReport;
use crate::inspect::Inspection;
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct DocumentSummary {
pub name: String,
pub title: String,
pub formula: String,
pub n_sites: usize,
pub volume: f64,
pub density: f64,
pub source: Option<String>,
pub dirty: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct BondSummary {
pub i: usize,
pub j: usize,
pub image: [i32; 3],
pub distance: f64,
pub order: f64,
pub explicit: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct HistoryEntry {
pub description: String,
pub origin: String,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct RingCount {
pub size: usize,
pub count: usize,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct PatternSample {
pub two_theta: f64,
pub intensity: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct SymmetrySummary {
pub number: u32,
pub hm_symbol: String,
pub pearson_symbol: String,
pub n_operations: usize,
pub n_atoms: usize,
pub wyckoffs: Vec<char>,
pub site_symmetries: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct PorositySummary {
pub spacing: f64,
pub probe_radius: f64,
pub cell_volume: f64,
pub accessible_volume: f64,
pub accessible_fraction: f64,
pub surface_area: f64,
pub largest_included_diameter: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct OptimizationSummary {
pub energy_ev: f64,
pub converged: bool,
pub steps: usize,
pub max_force_ev_per_angstrom: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum Answer {
Capabilities {
capabilities: Capabilities,
},
Documents {
documents: Vec<DocumentSummary>,
active: Option<String>,
},
Loaded {
document: DocumentSummary,
},
Saved {
document: String,
path: String,
format: String,
bytes: usize,
},
Info {
document: String,
inspection: Inspection,
diagnostics: DiagnosticReport,
},
Diagnostics {
document: String,
report: DiagnosticReport,
},
Structure {
document: String,
summary: DocumentSummary,
description: String,
},
Symmetry {
document: String,
symmetry: SymmetrySummary,
},
Bonds {
document: String,
n_atoms: usize,
bonds: Vec<BondSummary>,
},
Rings {
document: String,
max_size: usize,
counts: Vec<RingCount>,
total: usize,
},
Pxrd {
document: String,
radiation: String,
n_reflections: usize,
reflections: Vec<[f64; 2]>,
points: Vec<PatternSample>,
},
Porosity {
document: String,
porosity: PorositySummary,
},
Energy {
document: String,
energy_ev: f64,
n_atoms: usize,
max_force_ev_per_angstrom: f64,
stress_gpa: Option<[[f64; 3]; 3]>,
},
Optimization {
document: String,
optimization: OptimizationSummary,
summary: crate::inspect::StructureSummaryView,
},
Picture {
document: String,
format: String,
width: u32,
height: u32,
path: Option<String>,
bytes: Option<usize>,
},
History {
document: String,
applied: bool,
entries: Vec<HistoryEntry>,
can_undo: bool,
can_redo: bool,
},
Changes {
document: String,
bursts: Vec<ChangeBurst>,
},
}
impl Answer {
pub fn to_json(&self) -> Result<Value, crate::Error> {
serde_json::to_value(self).map_err(|error| crate::Error::Json(error.to_string()))
}
#[must_use]
pub fn kind(&self) -> &'static str {
match self {
Self::Capabilities { .. } => "capabilities",
Self::Documents { .. } => "documents",
Self::Loaded { .. } => "loaded",
Self::Saved { .. } => "saved",
Self::Info { .. } => "info",
Self::Diagnostics { .. } => "diagnostics",
Self::Structure { .. } => "structure",
Self::Symmetry { .. } => "symmetry",
Self::Bonds { .. } => "bonds",
Self::Rings { .. } => "rings",
Self::Pxrd { .. } => "pxrd",
Self::Porosity { .. } => "porosity",
Self::Energy { .. } => "energy",
Self::Optimization { .. } => "optimization",
Self::Picture { .. } => "picture",
Self::History { .. } => "history",
Self::Changes { .. } => "changes",
}
}
}