use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChartAlgorithmKind {
QuanShu,
Zhongzhou,
Placeholder,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChartPlane {
#[default]
Heaven,
Earth,
Human,
}
pub const fn is_valid_chart_algorithm_plane(
algorithm: ChartAlgorithmKind,
plane: ChartPlane,
) -> bool {
match (algorithm, plane) {
(
ChartAlgorithmKind::Zhongzhou,
ChartPlane::Heaven | ChartPlane::Earth | ChartPlane::Human,
) => true,
(ChartAlgorithmKind::QuanShu | ChartAlgorithmKind::Placeholder, ChartPlane::Heaven) => true,
(ChartAlgorithmKind::QuanShu | ChartAlgorithmKind::Placeholder, _) => false,
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct MethodProfile {
id: String,
algorithm_kind: ChartAlgorithmKind,
description: String,
}
impl MethodProfile {
pub fn new(
id: impl Into<String>,
algorithm_kind: ChartAlgorithmKind,
description: impl Into<String>,
) -> Self {
Self {
id: id.into(),
algorithm_kind,
description: description.into(),
}
}
pub fn placeholder(id: impl Into<String>) -> Self {
Self::new(
id,
ChartAlgorithmKind::Placeholder,
"placeholder method profile; chart algorithms are not implemented",
)
}
pub fn id(&self) -> &str {
&self.id
}
pub const fn algorithm_kind(&self) -> ChartAlgorithmKind {
self.algorithm_kind
}
pub fn description(&self) -> &str {
&self.description
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ChartProfile {
method_profile: MethodProfile,
#[serde(default)]
chart_plane: ChartPlane,
}
impl ChartProfile {
pub const fn new(method_profile: MethodProfile, chart_plane: ChartPlane) -> Self {
Self {
method_profile,
chart_plane,
}
}
pub const fn method_profile(&self) -> &MethodProfile {
&self.method_profile
}
pub const fn chart_plane(&self) -> ChartPlane {
self.chart_plane
}
pub const fn algorithm_kind(&self) -> ChartAlgorithmKind {
self.method_profile.algorithm_kind()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn chart_plane_default_is_heaven() {
assert_eq!(ChartPlane::default(), ChartPlane::Heaven);
}
#[test]
fn quanshu_heaven_is_valid() {
assert!(is_valid_chart_algorithm_plane(
ChartAlgorithmKind::QuanShu,
ChartPlane::Heaven,
));
}
#[test]
fn quanshu_earth_is_not_valid() {
assert!(!is_valid_chart_algorithm_plane(
ChartAlgorithmKind::QuanShu,
ChartPlane::Earth,
));
}
#[test]
fn quanshu_human_is_not_valid() {
assert!(!is_valid_chart_algorithm_plane(
ChartAlgorithmKind::QuanShu,
ChartPlane::Human,
));
}
#[test]
fn zhongzhou_heaven_is_valid() {
assert!(is_valid_chart_algorithm_plane(
ChartAlgorithmKind::Zhongzhou,
ChartPlane::Heaven,
));
}
#[test]
fn zhongzhou_earth_is_valid() {
assert!(is_valid_chart_algorithm_plane(
ChartAlgorithmKind::Zhongzhou,
ChartPlane::Earth,
));
}
#[test]
fn zhongzhou_human_is_valid() {
assert!(is_valid_chart_algorithm_plane(
ChartAlgorithmKind::Zhongzhou,
ChartPlane::Human,
));
}
#[test]
fn placeholder_heaven_is_valid() {
assert!(is_valid_chart_algorithm_plane(
ChartAlgorithmKind::Placeholder,
ChartPlane::Heaven,
));
}
#[test]
fn placeholder_earth_is_not_valid() {
assert!(!is_valid_chart_algorithm_plane(
ChartAlgorithmKind::Placeholder,
ChartPlane::Earth,
));
}
#[test]
fn placeholder_human_is_not_valid() {
assert!(!is_valid_chart_algorithm_plane(
ChartAlgorithmKind::Placeholder,
ChartPlane::Human,
));
}
#[test]
fn chart_profile_preserves_method_profile_and_plane() {
let method_profile =
MethodProfile::new("zhongzhou_test", ChartAlgorithmKind::Zhongzhou, "zhongzhou");
let profile = ChartProfile::new(method_profile.clone(), ChartPlane::Earth);
assert_eq!(profile.method_profile(), &method_profile);
assert_eq!(profile.chart_plane(), ChartPlane::Earth);
assert_eq!(profile.algorithm_kind(), ChartAlgorithmKind::Zhongzhou);
}
#[test]
fn chart_profile_defaults_are_independent_axes() {
let method_profile =
MethodProfile::new("quanshu_test", ChartAlgorithmKind::QuanShu, "quanshu");
let profile = ChartProfile::new(method_profile, ChartPlane::Heaven);
assert_eq!(profile.chart_plane(), ChartPlane::Heaven);
assert_eq!(profile.algorithm_kind(), ChartAlgorithmKind::QuanShu);
}
}