unobtanium 3.0.0

Opinioated Web search engine library with crawler and viewer companion.
Documentation
use serde::{Serialize,Deserialize};
use url::Url;
use uuid::Uuid;

use crate::database::id::EntityGenerationId;
use crate::time::UtcTimespan;
use crate::time::UtcTimestamp;

/// A way to describe spacetime coordinates on the Web
/// combining an Url with a Timespan.
#[derive(Debug,Clone,PartialEq,Eq,Serialize,Deserialize)]
pub struct EntityGeneration {

	/// The url under wich the entity lives
	pub url: Url,

	/// UUID (recommend v7 or v4) of the entity generation.
	/// Prefer this over the numeric database id when giving out entity generation ids
	/// to the outside world.
	pub uuid: Uuid,

	/// First known existence
	pub first_seen: UtcTimestamp,

	/// Latest known instance of this entity generation existing,
	/// this will get updated as new data comes in.
	pub last_seen: UtcTimestamp,

	/// Marker that gets updated in the database when the entity is detected to be a duplicate, gets imported into the database on initial insert.
	pub marked_duplicate: bool,

	/// Time at which it was confirmed that the entity generation no longer exists.
	///
	/// Either because it was replaced by a new one or marked as unavailable.
	///
	/// This should be equal to the `first_seen` of the following generation or outage.
	///
	/// Is `None` if the last time this was crawled the backing resource
	/// was in the state this EntityGeneration represents.
	///
	/// This marker might be reset to `None` in case
	/// the backing resource had a temporary outage.
	pub time_end_confirmed: Option<UtcTimestamp>,
}

impl EntityGeneration {
	
	/// Returns the timespan from first seen to `last_seen`.
	pub fn get_confirmed_lifetime(&self) -> UtcTimespan {
		UtcTimespan::new(Some(self.first_seen), Some(self.last_seen))
	}

	/// Returns the timespan from `first_seen` to `time_end_confirmed`.
	pub fn max_condifrmed_lifetime(&self) -> UtcTimespan {
		UtcTimespan::new(Some(self.first_seen), self.time_end_confirmed)
	}

	/// Helper that returns wheter the EntityGeneration thinks it is current information.
	///
	/// That is, it not having a confirmed end time.
	pub fn is_still_alive(&self) -> bool {
		self.time_end_confirmed.is_none()
	}
}

/// A wrapper struct for things related to a [EntityGeneration][self::EntityGeneration].
///
/// This struct uses the database id, for a serializable version, see the [WithEntityGenerationUuid] struct, that uses a publicly exposable UUID in place of the internal database id.
#[derive(Clone)]
//#[deprecated(note="Use `WithEntityGenerationUuid` instead.")]
pub struct WithEntityGenerationId<T> {

	/// The indentifier for the entity generation
	pub entity_generation_id: EntityGenerationId,

	/// The actual data
	pub data: T
}

pub trait IntoWithEntityGenerationId<T>
where T: Clone {
	
	/// Convert a datastructure to a [`WithEntityGenerationId`] containing it.
	///
	/// [`WithEntityGenerationId`]: self::WithEntityGenerationId
	fn with_entity_generation_id(self, id: EntityGenerationId) -> WithEntityGenerationId<T>;

}

impl<T> IntoWithEntityGenerationId<T> for T
where T: Clone {
	fn with_entity_generation_id(self, id: EntityGenerationId) -> WithEntityGenerationId<T> {
		WithEntityGenerationId {
			entity_generation_id: id,
			data: self,
		}
	}
}

/// A wrapper struct for things related to a [EntityGeneration][self::EntityGeneration].
#[derive(Clone, Deserialize, Serialize)]
pub struct WithEntityGenerationUuid<T> {

	/// The indentifier for the entity generation
	pub entity_generation_uuid: Uuid,

	/// The actual data
	#[serde(flatten)]
	pub data: T
}

pub trait IntoWithEntityGenerationUuid<T>
where T: Clone {
	
	/// Convert a datastructure to a [`WithEntityGenerationId`] containing it.
	///
	/// [`WithEntityGenerationId`]: self::WithEntityGenerationId
	fn with_entity_generation_uuid(self, uuid: Uuid) -> WithEntityGenerationUuid<T>;

}

impl<T> IntoWithEntityGenerationUuid<T> for T
where T: Clone {
	fn with_entity_generation_uuid(self, uuid: Uuid) -> WithEntityGenerationUuid<T> {
		WithEntityGenerationUuid {
			entity_generation_uuid: uuid,
			data: self,
		}
	}
}