daemonic_error 0.1.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::string::String;
use alloc::vec::Vec;
use core::ops::Deref;
use crate::daemonic::{daemonic_hasher, TopologySegment, TopologyAnchor, AnchorDomainSet};
use crate::daemonic::daemonic_hasher::{DaemonicHashable, DaemonicHasher};
use crate::daemonic::daemonic_hasher::random::DefaultDaemonicHasher;
use crate::daemonic::glass::Glass;

/// An owned, mutable path (akin to [`String`]).
///
/// This type provides methods like [`push`] and [`set_extension`] that mutate
/// the path in place. It also implements [`Deref`] to [`Path`], meaning that
/// all methods on [`Path`] slices are available on `PathBuf` values as well.
///
/// [`push`]: PathBuf::push
/// [`set_extension`]: PathBuf::set_extension
///
/// More details about the overall approach can be found in
/// the [module documentation](self).
///
/// # Examples
///
/// You can use [`push`] to build up a `PathBuf` from
/// components:
///
/// ```
/// use DaemonicError::PathBuf;
///
/// let mut path = PathBuf::new();
///
/// path.push(r"C:\");
/// path.push("windows");
/// path.push("system32");
///
/// path.set_extension("dll");
/// ```
///
/// However, [`push`] is best used for dynamic situations. This is a better way
/// to do this when you know all of the components ahead of time:
///
/// ```
/// use DaemonicError::PathBuf;
///
/// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
/// ```
///
/// We can still do better than this! Since these are all strings, we can use
/// `From::from`:
///
/// ```
/// use DaemonicError::PathBuf;
///
/// let path = PathBuf::from(r"C:\windows\system32.dll");
/// ```
///
/// Which method works best depends on what kind of situation you're in.
///
/// Note that `PathBuf` does not always sanitize arguments, for example
/// [`push`] allows paths built from strings which include separators:
///
/// ```
/// use DaemonicError::PathBuf;
///
/// let mut path = PathBuf::new();
///
/// path.push(r"C:\");
/// path.push("windows");
/// path.push(r"..\otherdir");
/// path.push("system32");
/// ```
///
/// The behavior of `PathBuf` may be changed to a panic on such inputs
/// in the future. [`Extend::extend`] should be used to add multi-part paths.
#[derive(Debug)]
pub struct DaemonicPathBuf {
	inner: DaemonicOsString,
}
/// A type that can represent owned, mutable platform-native strings, but is
/// cheaply inter-convertible with Rust strings.
///
/// The need for this type arises from the fact that:
///
/// * On Unix systems, strings are often arbitrary sequences of non-zero
///   bytes, in many cases interpreted as UTF-8.
///
/// * On Windows, strings are often arbitrary sequences of non-zero 16-bit
///   values, interpreted as UTF-16 when it is valid to do so.
///
/// * In Rust, strings are always valid UTF-8, which may contain zeros.
///
/// `OsString` and [`OsStr`] bridge this gap by simultaneously representing Rust
/// and platform-native string values, and in particular allowing a Rust string
/// to be converted into an "OS" string with no cost if possible. A consequence
/// of this is that `OsString` instances are *not* `NUL` terminated; in order
/// to pass to e.g., Unix system call, you should create a [`CStr`].
///
/// `OsString` is to <code>&[OsStr]</code> as [`String`] is to <code>&[str]</code>: the former
/// in each pair are owned strings; the latter are borrowed
/// references.
///
/// Note, `OsString` and [`OsStr`] internally do not necessarily hold strings in
/// the form native to the platform; While on Unix, strings are stored as a
/// sequence of 8-bit values, on Windows, where strings are 16-bit value based
/// as just discussed, strings are also actually stored as a sequence of 8-bit
/// values, encoded in a less-strict variant of UTF-8. This is useful to
/// understand when handling capacity and length values.
///
/// # Capacity of `OsString`
///
/// Capacity uses units of UTF-8 bytes for OS strings which were created from valid unicode, and
/// uses units of bytes in an unspecified encoding for other contents. On a given target, all
/// `OsString` and `OsStr` values use the same units for capacity, so the following will work:
/// ```
/// use std::ffi::{OsStr, OsString};
///
/// fn concat_os_strings(a: &OsStr, b: &OsStr) -> OsString {
///     let mut ret = OsString::with_capacity(a.len() + b.len()); // This will allocate
///     ret.push(a); // This will not allocate further
///     ret.push(b); // This will not allocate further
///     ret
/// }
/// ```
///
/// # Creating an `OsString`
///
/// **From a Rust string**: `OsString` implements
/// <code>[From]<[String]></code>, so you can use <code>my_string.[into]\()</code> to
/// create an `OsString` from a normal Rust string.
///
/// **From slices:** Just like you can start with an empty Rust
/// [`String`] and then [`String::push_str`] some <code>&[str]</code>
/// sub-string slices into it, you can create an empty `OsString` with
/// the [`OsString::new`] method and then push string slices into it with the
/// [`OsString::push`] method.
///
/// # Extracting a borrowed reference to the whole OS string
///
/// You can use the [`OsString::as_os_str`] method to get an <code>&[OsStr]</code> from
/// an `OsString`; this is effectively a borrowed reference to the
/// whole string.
///
/// # Conversions
///
/// See the [module's toplevel documentation about conversions][conversions] for a discussion on
/// the traits which `OsString` implements for [conversions] from/to native representations.
///
/// [`CStr`]: crate::ffi::CStr
/// [conversions]: super#conversions
/// [into]: Into::into
#[derive(Debug)]
pub struct DaemonicOsString {
	inner: DaemonicBuf,
}
// #[crate::daemonic(hash)]
#[derive(Debug)]
#[repr(transparent)]
pub struct DaemonicBuf {
	pub inner: Vec<u8>,
}
const DAEMONICBUF_TOPOLOGY: TopologySegment = TopologySegment {
	label: "Daemonic::Glass::Consumer::DaemonicBuf",
	hash: crate::const_daemonic_hash(
		"Daemonic::Glass::Consumer::DaemonicBuf".as_bytes(),
		crate::AXIOM_OFFSET,
	),
	crypto_id: crate::const_daemonic_hash(
		"Daemonic::Glass::Consumer::DaemonicBuf".as_bytes(),
		crate::TOPOLOGY_ANCHOR,
	),
	depth: 3u16,
};
impl crate::daemonic::Anchor for DaemonicBuf {
	fn anchor_domains(&self) -> AnchorDomainSet {
		AnchorDomainSet::SPATIAL
			.union(AnchorDomainSet::STRUCTURAL)
			.union(AnchorDomainSet::SYMBOLIC)
	}
}
impl crate::daemonic::SymbolicAnchor for DaemonicBuf {
	type Anchor = TopologySegment;
	fn meaningful_within(&self) -> Self::Anchor {
		DAEMONICBUF_TOPOLOGY.clone()
	}
}
impl crate::daemonic::SemanticAnchor for DaemonicBuf {}
impl crate::daemonic::SpatialAnchor for DaemonicBuf {
	fn anchor_position(&self) -> &TopologySegment {
		&DAEMONICBUF_TOPOLOGY
	}
	fn neighbors(&self) -> TopologySegment {
		DAEMONICBUF_TOPOLOGY.clone()
	}
}
impl crate::daemonic::StructuralAnchor for DaemonicBuf {
	fn contract_description(&self) -> &str {
		"DaemonicBuf: auto-derived Daemonic anchor via #[daemonic] proc macro"
	}
}
impl crate::TopologyAnchor for DaemonicBuf {
	fn parent(&self) -> Option<TopologySegment> {
		let label = DAEMONICBUF_TOPOLOGY.label;
		label
			.rsplit_once("::")
			.map(|(parent, _)| <TopologySegment as TopologyAnchor>::new_anchor(parent))
	}
	fn children(&self) -> &[TopologySegment] {
		&[]
	}
	fn segments(&self) -> &TopologySegment {
		&DAEMONICBUF_TOPOLOGY
	}
	fn depth(&self) -> usize {
		DAEMONICBUF_TOPOLOGY.depth as usize
	}
}
impl DaemonicHashable for DaemonicBuf {
	fn declare_hashable<GLASS: DaemonicHasher<GLASS> + Glass<GLASS>>(&self, state: &mut GLASS)
	{
		DaemonicHashable::declare_hashable(&self.inner, state);
	}
}
impl DaemonicHashable for Vec<u8> {
	fn declare_hashable<GLASS: DaemonicHasher<GLASS> + Glass<GLASS>>(&self, state: &mut GLASS) {
		let x = self;
		let mut object = state;
		let object = DefaultDaemonicHasher::new();
		// object.
		// self.declare_hashable()
		
		
		todo!()
	}
}