use alloc::borrow::ToOwned;
use alloc::string::String;
use core::fmt::{Debug, Formatter};
use daemonic_error::daemonic::{Anchor, SemanticAnchor, SpatialAnchor, StructuralAnchor, SymbolicAnchor};
use daemonic_error::{Observation, TopologyAnchor};
use super::{Glass, GlassStable, Stable};
use crate::daemonic::glass::Severity;
use crate::{Annotation, DaemonicError, DaemonicVariants, Error, ObservationTier, Temporal, TopologySegment};
use crate::daemonic::frame::{Frame, FrameType, ReferenceFrame};
use crate::daemonic::glass::error::GlassError;
use super::super::super::glass_flags::GlassFlags;
use super::super::super::states::cracked::GlassCracked;
#[derive(Clone, Debug)]
pub struct Cracked<GLASS> {
position: &'static TopologySegment,
severity: Severity,
tier: ObservationTier,
annotation: Annotation,
temporal: Temporal,
payload: Option<GLASS>,
flags: GlassFlags,
}
impl<GLASS> Cracked<GLASS> {
pub fn new(payload: Option<GLASS>, topology: &'static TopologySegment) -> Self {
Cracked {
position: &topology,
severity: Severity::Cracked,
tier: ObservationTier::Composed,
annotation: Annotation::None,
temporal: Temporal::Current,
payload,
flags: GlassFlags::cracked_defaults(),
}
}
pub fn extract_flags(&self) -> GlassFlags {
self.flags
}
pub fn extract_position(&self) -> &'static TopologySegment { self.position }
pub fn extract_position_label(&self) -> &str { self.position.label }
pub fn extract_tier(&self) -> ObservationTier { self.tier }
pub fn extract_annotation(&self) -> Annotation { self.annotation.clone() }
pub fn extract_temporal(&self) -> Temporal { self.temporal }
pub fn query_payload(&self) -> Option<&GLASS> {
self.extract_referent_payload()
}
pub fn query_payload_existence(&self) -> bool {
self.payload.is_some()
}
pub fn extract_severity(&self) -> Severity {
self.severity
}
pub fn mutate_annotation(&mut self, a: Annotation) {
self.annotation = a;
}
pub fn extract_referent_payload(&self) -> Option<&GLASS> {
self.payload.as_ref()
}
pub fn extract_owned_payload(self) -> Option<GLASS> {
self.payload
}
pub fn with_note(mut self, note: impl Into<String>) -> Self {
self.annotation = Annotation::Note(note.into());
self
}
pub fn with_suggestion(mut self, suggestion: impl Into<String>) -> Self {
self.annotation = Annotation::Suggestion(suggestion.into());
self
}
pub fn with_help(mut self, help: impl Into<String>) -> Self {
self.annotation = Annotation::Suggestion(help.into());
self
}
pub fn mutate_tier(mut self, tier: impl Into<ObservationTier>) -> Self {
self.tier = tier.into();
self
}
}
impl<GLASS> GlassCracked<GLASS> for Cracked<GLASS>
where
GLASS: Glass<GLASS> + Glass<Cracked<GLASS>> + for<'error> DaemonicError<'error>,
{
fn is_holding(&self) -> bool {
true
}
fn contain(&mut self) -> bool { false }
}
impl<GLASS> Glass<GLASS> for Cracked<GLASS> {
type Anchor = TopologySegment;
fn position(&self) -> &TopologySegment {
self.extract_position()
}
fn severity(&self) -> Severity {
self.extract_severity()
}
fn payload(&self) -> Option<&GLASS> {
self.extract_referent_payload()
}
fn into_payload(self) -> Option<GLASS>
where
Self: Sized,
GLASS: Sized,
{
self.extract_owned_payload()
}
}
pub const CRACKED_TOPOLOGY: TopologySegment = TopologySegment::new("Daemonic::Glass::States::Cracked<GLASS>");
impl<GLASS> Anchor for Cracked<GLASS> {
fn anchor_domains(&self) -> ::daemonic_error::daemonic::AnchorDomainSet {
::daemonic_error::daemonic::AnchorDomainSet::SPATIAL
.union(::daemonic_error::daemonic::AnchorDomainSet::STRUCTURAL)
.union(::daemonic_error::daemonic::AnchorDomainSet::SYMBOLIC)
}
}
impl<GLASS> SymbolicAnchor for Cracked<GLASS> {
type Anchor = TopologySegment;
fn meaningful_within(&self) -> Self::Anchor {
CRACKED_TOPOLOGY.clone()
}
}
impl<GLASS> SemanticAnchor for Cracked<GLASS> {}
impl<GLASS> SpatialAnchor for Cracked<GLASS> {
fn anchor_position(&self) -> &TopologySegment {
&CRACKED_TOPOLOGY
}
fn neighbors(&self) -> TopologySegment {
CRACKED_TOPOLOGY.clone()
}
}
impl<GLASS> StructuralAnchor for Cracked<GLASS> {
fn contract_description(&self) -> &str {
"Cracked: auto-derived Daemonic anchor via #[daemonic] proc macro"
}
}
impl<GLASS> TopologyAnchor for Cracked<GLASS> {
fn parent(&self) -> Option<TopologySegment> {
let label = CRACKED_TOPOLOGY.label;
label.rsplit_once("::").map(|(parent, _)| {
<TopologySegment as TopologyAnchor>::new_anchor(
parent,
)
})
}
fn children(&self) -> &[TopologySegment] {
&[]
}
fn segments(&self) -> &TopologySegment {
&self.position
}
fn depth(&self) -> usize {
self.position.depth as usize
}
}
impl<'error, GLASS: Glass<Cracked<GLASS>> + 'error> DaemonicError<'error> for Cracked<GLASS> {
fn emit(self) -> crate::DaemonicEmission {
todo!()
}
fn position(&self) -> &TopologySegment {
self.extract_position()
}
}
impl<GLASS: Glass<GLASS> + Glass<Cracked<GLASS>>> Frame for Cracked<GLASS> {
fn frame_type(&self) -> FrameType {
FrameType::Reference
}
}
impl<GLASS: Glass<GLASS> + Glass<Cracked<GLASS>>> ReferenceFrame for Cracked<GLASS> {
fn origin(&self) -> &TopologySegment {
todo!()
}
}