agent-tk 0.4.0

`agent-tk` (`agent toolkit/tasks-knowledge`) is a crate for the development of autonomous agents using Rust, with an emphasis on tasks and knowledge based agents. This project is part of the [auKsys](http://auksys.org) project.
Documentation
//! Wrap a u128 as a UUID

use std::fmt::Debug;

use crate::Result;

/// Store a UUID
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Uuid
{
  data: u128,
}

impl Uuid
{
  /// Generate a new UUID
  pub fn new() -> Self
  {
    Self {
      data: uuid::Uuid::new_v4().as_u128(),
    }
  }
  /// Convert this UUID into a hex representation
  pub fn to_hex(&self) -> String
  {
    hex::encode(self.data.to_le_bytes())
  }
  /// Parse a UUID from a string representation
  pub fn from_string(input: &str) -> Result<Self>
  {
    Ok(
      uuid::Uuid::parse_str(input)
        .map_err(|e| crate::Error::InvalidUuid(input.to_string(), e.to_string()))?
        .into(),
    )
  }
}

impl Default for Uuid
{
  fn default() -> Self
  {
    Self::new()
  }
}

impl From<uuid::Uuid> for Uuid
{
  fn from(data: uuid::Uuid) -> Self
  {
    Self {
      data: data.as_u128(),
    }
  }
}

impl From<u128> for Uuid
{
  fn from(data: u128) -> Self
  {
    Self { data }
  }
}

impl From<Uuid> for u128
{
  fn from(val: Uuid) -> Self
  {
    val.data
  }
}

impl Debug for Uuid
{
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
  {
    uuid::Uuid::from_u128(self.data).fmt(f)
  }
}

impl std::fmt::Display for Uuid
{
  /// Convert a UUID into a hyphenated string representation
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
  {
    write!(f, "{}", uuid::Uuid::from_u128(self.data).hyphenated())
  }
}

//  ____               _
// / ___|  ___ _ __ __| | ___
// \___ \ / _ \ '__/ _` |/ _ \
//  ___) |  __/ | | (_| |  __/
// |____/ \___|_|  \__,_|\___|

impl serde::Serialize for Uuid
{
  fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
  where
    S: serde::Serializer,
  {
    serializer.serialize_str(self.to_string().as_str())
  }
}

struct UuidVisitor;

impl<'de> serde::de::Visitor<'de> for UuidVisitor
{
  type Value = Uuid;

  fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
  {
    formatter.write_str("a valid UUID string")
  }
  fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
  where
    E: serde::de::Error,
  {
    Uuid::from_string(v).map_err(|e| {
      E::custom(format!(
        "Failed to parse UUID string {} with error {}",
        v, e
      ))
    })
  }
  fn visit_string<E>(self, v: String) -> std::result::Result<Self::Value, E>
  where
    E: serde::de::Error,
  {
    self.visit_str(v.as_str())
  }
}

impl<'de> serde::Deserialize<'de> for Uuid
{
  fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
  where
    D: serde::Deserializer<'de>,
  {
    deserializer.deserialize_str(UuidVisitor)
  }
}