unobtanium 3.0.0

Opinioated Web search engine library with crawler and viewer companion.
Documentation
//! ID types for interacting with the databases.

use rusqlite::{types::{FromSql, FromSqlResult, ToSqlOutput, Value, ValueRef}, ToSql};

use std::{fmt::Display, hash::Hash};

/// Id of an agent in the crawler database.
///
/// Outside of database code this should be treated like an opaque datatype.
///
/// TODO: Remove Default when agents have UUIDs
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Default)]
pub struct AgentId(i64);

/// Id of a crawl log entry in the crawler database.
///
/// Outside of database code this should be treated like an opaque datatype.
///
/// TODO: Remove Default when agents have UUIDs
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Default)]
pub struct CrawlLogEntryId(i64);

/// Id of a crawl summary in the summary database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct CrawlSummaryId(i64);

/// Id of a entity-generation in the summary database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct EntityGenerationId(i64);

/// Id of a file-info in the crawler database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct FileInfoId(i64);

/// Id of a mime-type in the base database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct MimetypeId(i64);

/// Id of an origin in the base database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct OriginId(i64);

/// Id of a redirect in the crawler database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct RedirectId(i64);

/// Id of a request in the crawler database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct RequestId(i64);

/// Id of a token in the summary database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct TokenId(i64);


/// Id of an url in the base database.
///
/// Outside of database code this should be treated like an opaque datatype.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct UrlId(i64);



/// Makes the numbers inside the otherwise opaque ids accessible to the outside world.
pub trait NumericDatabseId: Eq + Clone + Copy + Hash {

	/// Create a new id from a number.
	///
	/// There should be no need to call this outside of database code.
    fn new(id: i64) -> Self;

    
	/// Get the numeric id.
	///
	/// There should be no need to use this outside of database code.
	fn number(&self) -> i64;
}

impl NumericDatabseId for i64 {
	fn new(id: i64) -> Self {
	    id
	}

	fn number(&self) -> i64 {
	    *self
	}
}

macro_rules! impl_id {
	($t:ty) => {
		impl NumericDatabseId for $t {

			#[inline]
			fn new(id: i64) -> Self {
				Self(id)
			}

			#[inline]
			fn number(&self) -> i64 {
				self.0
			}
		}


		impl FromSql for $t {
			fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
			    Ok(Self(value.as_i64()?))
			}
		}

		impl ToSql for $t {
			fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
				Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
			}
		}

		impl Display for $t {
			fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
				f.write_fmt(format_args!("{}", self.0))
			}
		}

	}
}


impl_id!(AgentId);
impl_id!(CrawlLogEntryId);
impl_id!(CrawlSummaryId);
impl_id!(EntityGenerationId);
impl_id!(FileInfoId);
impl_id!(MimetypeId);
impl_id!(OriginId);
impl_id!(RedirectId);
impl_id!(RequestId);
impl_id!(TokenId);
impl_id!(UrlId);