daemonic_error 1.0.0

Errors that compose, predict, and leave receipts - Compose: algebraic combination (in active development) - Predict: Glass/Severity - Receipts: audit trail, position, checksum - Reflection: Runtime Reflection through TopologySegment (in active development)
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 mutate_tier(&self, t: ObservationTier) -> Self {
	// 	Cracked {
	// 		position: &self.position,
	// 		severity: self.severity,
	// 		tier: t,
	// 		annotation: self.extract_annotation(),
	// 		temporal: self.extract_temporal(),
	// 		payload: self.query_payload(),
	// 		flags: self.extract_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 }
	/// Cracked states by definition may or may not have a value, but usually do.
	/// This method checks, if payload is present at callsite -> returns Some<GLASS>, else returns None
	pub fn query_payload(&self) -> Option<&GLASS> {
		self.extract_referent_payload()
	}
	
	pub fn query_payload_existence(&self) -> bool {
		self.payload.is_some()
	}
	/// This method seems redundant, but theres a reason for its existence, States declare their own severity
	/// as well as the label. One reason is due to a ton of shit already using severity, but also
	/// explicitness.
	/// The old Observation State struct had public fields and was generic by design, States should
	/// be equated with Severity.
	/// IE Severity == State == Severity
	/// So as an additional safety precaution, the new structures are no longer field public, constructors
	/// extract data and pass to the consumer. Call site declarations should reflect this.
	/// Use extractor functions, dont exfil field data.
	pub fn extract_severity(&self) -> Severity {
		self.severity
	}
	// pub fn with_note(&self, note: impl Into<String>) -> Self {
	// 	Cracked {
	// 		position: &Self::extract_position(&self),
	// 		severity: Severity::Cracked,
	// 		tier: Self::extract_tier(&self),
	// 		annotation: Annotation::Note(note.into()),
	// 		temporal: Temporal::Current,
	// 		payload: self.query_payload(),
	// 		flags: self.extract_flags(),
	// 	}
	// }
	// pub fn with_suggestion(&self, suggestion: impl Into<String>) -> Self {
	// 	Cracked {
	// 		position: &Self::extract_position(&self),
	// 		severity: Severity::Cracked,
	// 		tier: Self::extract_tier(&self),
	// 		annotation: Annotation::Suggestion(suggestion.into()),
	// 		temporal: Temporal::Current,
	// 		payload: self.query_payload(),
	// 		flags: self.extract_flags(),
	// 	}
	// }
	// pub fn with_help(&self, help: impl Into<String>) -> Self {
	// 	Cracked {
	// 		position: &Self::extract_position(&self),
	// 		severity: Severity::Cracked,
	// 		tier: Self::extract_tier(&self),
	// 		annotation: Annotation::Help(help.into()),
	// 		temporal: Temporal::Current,
	// 		payload: self.query_payload(),
	// 		flags: self.extract_flags(),
	// 	}
	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>,
{
	/// By default, cracked glass states should be considered light errors so are holding, this must
	/// be set to false at callsite definition site.
	fn is_holding(&self) -> bool {
		true
	}
	/// By default a cracked return should not be contained, cracked errors by default
	/// are not dangerous errors.
	/// Set at callsite during escalation or if an error could be a light error but have side effects
	/// that dont smash active state.
	fn contain(&mut self) -> bool { false }
}
// impl<'error, GLASS: Glass<GLASS> + 'error> GlassCracked<Cracked<GLASS>> for Cracked<GLASS>
// 	where
// 		Cracked<GLASS>: Glass<Cracked<GLASS>> + 'error,
// 		GLASS: Glass<Cracked<GLASS>> + 'error,
// {
// 	/// By default, cracked glass states should be considered light errors so are holding, this must
// 	/// be set to false at callsite definition site.
// 	fn is_holding(&self) -> bool { true }
//
// 	/// By default a cracked return should not be contained, cracked errors by default
// 	/// are not dangerous errors.
// 	/// Set at callsite during escalation or if an error could be a light error but have side effects
// 	/// that dont smash active state.
// 	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.query_payload().as_ref()
		// self.payload.as_ref()
		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> {
	/// Returns a combined set of anchor domains by uniting the SPATIAL, STRUCTURAL,
	/// and SYMBOLIC domains from the `AnchorDomainSet`.
	///
	/// This function is designed to provide a comprehensive set of anchor domains
	/// relevant to the current use case. The union operation ensures that the resulting
	/// set includes all the specified domains:
	///
	/// - `SPATIAL`: Pertains to spatial relationships or contexts.
	/// - `STRUCTURAL`: Relates to structural or hierarchical contexts.
	/// - `SYMBOLIC`: Involves symbolic or abstract contexts.
	///
	/// # Returns
	/// A `AnchorDomainSet` instance containing the union of the SPATIAL, STRUCTURAL,
	/// and SYMBOLIC anchor domains.
	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;
	/// Returns a clone of the `CRACKED_TOPOLOGY` constant, representing an anchor
	/// associated with the current instance of the type implementing this method.
	///
	/// # Returns
	///
	/// An instance of `Self::Anchor` which is a cloned static value.
	///
	/// # Notes
	/// - The method leverages the `clone` implementation of `CRACKED_TOPOLOGY`.
	/// - Ensure `CRACKED_TOPOLOGY` is a valid and accessible constant within the scope.
	/// - Intended to provide a meaningful anchor for the current instance's topology.
	///
	/// # Example
	/// ```rust
	/// let anchor = instance.meaningful_within();
	/// // `anchor` now holds a cloned value of `CRACKED_TOPOLOGY`.
	/// ```
	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
	}
	/// Returns a `TopologySegment` representing the neighbors of the current structure.
	///
	/// This function retrieves a copy of the constant `CRACKED_TOPOLOGY` that defines
	/// the topology of neighboring segments. It is assumed that `CRACKED_TOPOLOGY`
	/// is predefined elsewhere in the code and represents the structure's neighborhood
	/// relationship in some topological context.
	///
	/// # Returns
	///
	/// * `TopologySegment` - A clone of the `CRACKED_TOPOLOGY` constant.
	///
	/// # Example
	///
	/// ```rust
	/// let segment = some_structure.neighbors();
	/// ```
	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
	}
	/// Returns the depth value of the current object.
	///
	/// This method retrieves the depth from the `position` field of the object
	/// and casts it to a `usize` before returning it.
	///
	/// # Returns
	/// * `usize` - The depth value of the current object.
	///
	/// # Example
	/// ```
	/// let obj = SomeObject { position: Position { depth: 10 } };
	/// let depth = obj.depth();
	/// assert_eq!(depth, 10);
	/// ```
	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!()
		// let obs = crate::daemonic::observation::Stable::new(&self, self.extract_position());
		// let pos = self.extract_position();
		//todo
		// GOD DAMNIT THIS DOESNT WORK AND IT SHOULD BUT IT DOESNT AND IT MAKES ME ANGRY
		// crate::DaemonicEmission::new(crate::daemonic::observation::obs_states::Stable::new(self, pos))
		// crate::DaemonicEmission {
		// 	inner: alloc::boxed::Box::new(
		// 		crate::daemonic::observation::obs_states::Stable::new(self.to_owned(), &self.extract_position())
		// 	),
		// }
	}
	
	fn position(&self) -> &TopologySegment {
		self.extract_position()
	}
}
impl<GLASS: Glass<GLASS> + Glass<Cracked<GLASS>>> Frame for Cracked<GLASS> {
	/// i dont like this logic, but this works for now and marks the intent.
	/// Ideally, Reference<GLASS> would actually be Reference<Cracked<GLASS>> but it wont let me express that because rust is sometimes a dick.
	fn frame_type(&self) -> FrameType {
		FrameType::Reference
	}
}
impl<GLASS: Glass<GLASS> + Glass<Cracked<GLASS>>> ReferenceFrame for Cracked<GLASS> {
	fn origin(&self) -> &TopologySegment {
		todo!()
	}
}