use crate::Node;
use crate::NodeLocation;
use crate::NodeStr;
use std::hash;
use std::ops::Deref;
use std::ops::DerefMut;
use triomphe::Arc;
#[derive(Debug, Clone)]
pub struct Component<T> {
pub origin: ComponentOrigin,
pub node: Node<T>,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum ComponentOrigin {
Definition,
Extension(ExtensionId),
}
#[derive(Debug, Clone, Eq)]
pub struct ExtensionId {
arc: Arc<Option<NodeLocation>>,
}
impl ExtensionId {
pub fn new<T>(extension: &Node<T>) -> Self {
Self {
arc: Arc::new(extension.location()),
}
}
pub fn location(&self) -> Option<NodeLocation> {
*self.arc
}
pub fn same_location<T>(&self, node: T) -> Node<T> {
Node::new_opt_location(node, self.location())
}
}
impl PartialEq for ExtensionId {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.arc, &other.arc)
}
}
impl hash::Hash for ExtensionId {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
Arc::as_ptr(&self.arc).hash(state);
}
}
impl ComponentOrigin {
pub fn extension_id(&self) -> Option<&ExtensionId> {
match self {
ComponentOrigin::Definition => None,
ComponentOrigin::Extension(id) => Some(id),
}
}
}
impl<T> Component<T> {
pub fn new(node: T) -> Self {
Self {
origin: ComponentOrigin::Definition,
node: Node::new(node),
}
}
}
impl<T: hash::Hash> hash::Hash for Component<T> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.node.hash(state); }
}
impl<T: Eq> Eq for Component<T> {}
impl<T: PartialEq> PartialEq for Component<T> {
fn eq(&self, other: &Self) -> bool {
self.node == other.node }
}
impl<T> Deref for Component<T> {
type Target = Node<T>;
fn deref(&self) -> &Self::Target {
&self.node
}
}
impl<T> DerefMut for Component<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.node
}
}
impl<T> AsRef<T> for Component<T> {
fn as_ref(&self) -> &T {
&self.node
}
}
impl<T> From<T> for Component<T> {
fn from(node: T) -> Self {
Component::new(node)
}
}
#[derive(Debug, Clone)]
pub struct ComponentStr {
pub origin: ComponentOrigin,
pub node: NodeStr,
}
impl ComponentStr {
#[inline]
pub fn new(value: &str) -> Self {
Self {
origin: ComponentOrigin::Definition,
node: NodeStr::new(value),
}
}
}
impl hash::Hash for ComponentStr {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.node.hash(state); }
}
impl Eq for ComponentStr {}
impl PartialEq for ComponentStr {
fn eq(&self, other: &Self) -> bool {
self.node == other.node }
}
impl PartialEq<str> for ComponentStr {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl Deref for ComponentStr {
type Target = NodeStr;
#[inline]
fn deref(&self) -> &Self::Target {
&self.node
}
}
impl std::borrow::Borrow<NodeStr> for ComponentStr {
fn borrow(&self) -> &NodeStr {
self
}
}
impl std::borrow::Borrow<str> for ComponentStr {
fn borrow(&self) -> &str {
self
}
}
impl AsRef<str> for ComponentStr {
fn as_ref(&self) -> &str {
self
}
}
impl From<&'_ str> for ComponentStr {
fn from(value: &'_ str) -> Self {
Self::new(value)
}
}
impl From<&'_ String> for ComponentStr {
fn from(value: &'_ String) -> Self {
Self::new(value)
}
}
impl From<String> for ComponentStr {
fn from(value: String) -> Self {
Self::new(&value)
}
}