use crate::BlankId;
use std::convert::TryFrom;
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct BlankIdIndex(usize);
impl From<usize> for BlankIdIndex {
fn from(i: usize) -> Self {
Self(i)
}
}
impl From<BlankIdIndex> for usize {
fn from(value: BlankIdIndex) -> Self {
value.0
}
}
impl IndexedBlankId for BlankIdIndex {
fn blank_id_index(&self) -> BlankIdOrIndex<&'_ BlankId> {
BlankIdOrIndex::Index(self.0)
}
}
impl<'a> TryFrom<&'a BlankId> for BlankIdIndex {
type Error = ();
fn try_from(_value: &'a BlankId) -> Result<Self, Self::Error> {
Err(())
}
}
#[cfg(feature = "contextual")]
impl<V: crate::vocabulary::BlankIdVocabulary<BlankId = Self>> contextual::DisplayWithContext<V> for BlankIdIndex {
fn fmt_with(&self, vocabulary: &V, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(&vocabulary.blank_id(self).unwrap(), f)
}
}
#[cfg(feature = "contextual")]
impl<V: crate::vocabulary::BlankIdVocabulary<BlankId = Self>> crate::RdfDisplayWithContext<V> for BlankIdIndex {
fn rdf_fmt_with(&self, vocabulary: &V, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(&vocabulary.blank_id(self).unwrap(), f)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub enum BlankIdOrIndex<B> {
Index(usize),
BlankId(B),
}
impl<I> From<usize> for BlankIdOrIndex<I> {
fn from(i: usize) -> Self {
Self::Index(i)
}
}
impl<'a, I: TryFrom<&'a BlankId>> TryFrom<&'a BlankId> for BlankIdOrIndex<I> {
type Error = I::Error;
fn try_from(value: &'a BlankId) -> Result<Self, Self::Error> {
Ok(Self::BlankId(I::try_from(value)?))
}
}
pub trait IndexedBlankId: From<usize> + for<'a> TryFrom<&'a BlankId> {
fn blank_id_index(&self) -> BlankIdOrIndex<&'_ BlankId>;
}
impl<B> IndexedBlankId for BlankIdOrIndex<B>
where
B: AsRef<BlankId> + for<'a> TryFrom<&'a BlankId>,
{
fn blank_id_index(&self) -> BlankIdOrIndex<&'_ BlankId> {
match self {
Self::BlankId(i) => BlankIdOrIndex::BlankId(i.as_ref()),
Self::Index(i) => BlankIdOrIndex::Index(*i),
}
}
}