use crate::symbols::*;
use serde::{Deserialize, Serialize};
use std::ops::{Deref, DerefMut};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum TLinkType {
SELF,
Component,
Compound,
ComponentStatement,
CompoundStatement,
ComponentCondition,
CompoundCondition,
Transform,
}
impl TLinkType {
pub fn to_order(&self) -> usize {
use TLinkType::*;
match self {
SELF => 0,
Component => 1,
Compound => 2,
ComponentStatement => 3,
CompoundStatement => 4,
ComponentCondition => 5,
CompoundCondition => 6,
Transform => 8,
}
}
pub fn is_to_component(&self) -> bool {
use TLinkType::*;
matches!(self, Component | ComponentStatement | ComponentCondition)
}
pub fn is_to_compound(&self) -> bool {
use TLinkType::*;
matches!(self, Compound | CompoundStatement | CompoundCondition)
}
pub fn try_point_to_component(self) -> Self {
use TLinkType::*;
match self {
Compound => Component,
ComponentStatement => ComponentStatement,
CompoundStatement => ComponentStatement,
CompoundCondition => ComponentCondition,
_ => panic!("不支持的转换:{self:?}"),
}
}
}
pub trait TLink<Target> {
fn target<'r, 's: 'r>(&'s self) -> impl Deref<Target = Target> + 'r;
fn target_mut<'r, 's: 'r>(&'s mut self) -> impl DerefMut<Target = Target> + 'r;
fn link_type(&self) -> TLinkType;
fn indexes(&self) -> &[usize];
#[doc(alias = "generate_key")]
fn generate_key_base(link_type: TLinkType, indexes: &[usize]) -> String {
let [at1, at2] = match link_type.is_to_component() {
true => TO_COMPONENT,
false => TO_COMPOUND,
};
let mut inner = format!("T{}", link_type.to_order());
for index in indexes {
inner += "-";
inner += &(index + 1).to_string();
}
format!("{at1}{inner}{at2}")
}
fn get_index(&self, index: usize) -> Option<&usize> {
self.indexes().get(index)
}
fn index(&self, index: usize) -> usize {
self.indexes()[index]
}
}