Skip to content

Commit

Permalink
Cleaned up docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Mar 24, 2021
1 parent f7def28 commit a2a0e32
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 125 deletions.
24 changes: 12 additions & 12 deletions core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ use crate::{
Error,
};

/// a trait that defines all interactions with a `Database`, regardless of whether it is local or remote
/// Defines all interactions with a `Database`, regardless of whether it is local or remote.
#[async_trait]
pub trait Connection<'a>: Send + Sync {
/// access a collection for the connected `Database`
/// Accesses a collection for the connected `Database`.
fn collection<C: schema::Collection + 'static>(
&'a self,
) -> Result<Collection<'a, Self, C>, Error>
where
Self: Sized;

/// insert a newly created document into the connected `Database` for the collection `C`
/// Inserts a newly created document into the connected `Database` for the collection `C`.
async fn insert<C: schema::Collection>(&self, contents: Vec<u8>) -> Result<Header, Error>;

/// update an existing document in the connected `Database` for the
/// Updates an existing document in the connected `Database` for the
/// collection `C`. Upon success, `doc.revision` will be updated with the
/// new revision.
async fn update(&self, doc: &mut Document<'_>) -> Result<(), Error>;

/// retrieve a stored document from collection `C` identified by `id`
/// Retrieves a stored document from collection `C` identified by `id`.
async fn get<C: schema::Collection>(
&self,
id: Uuid,
) -> Result<Option<Document<'static>>, Error>;

/// apply a transaction to the database. If any operation in the transaction
/// Applies a transaction to the database. If any operation in the transaction
/// fails, none of the operations will be applied to the database.
async fn apply_transaction(
&self,
transaction: Transaction<'static>,
) -> Result<Vec<OperationResult>, Error>;

/// list executed transactions from this database. By default, a maximum of
/// Lists executed transactions from this database. By default, a maximum of
/// 1000 entries will be returned, but that limit can be overridden by
/// setting `result_limit`. A hard limit of 100,000 results will be
/// returned. To begin listing after another known `transaction_id`, pass
Expand All @@ -54,7 +54,7 @@ pub trait Connection<'a>: Send + Sync {
) -> Result<Vec<transaction::Executed<'static>>, Error>;
}

/// a struct used to interact with a collection over a `Connection`
/// Interacts with a collection over a `Connection`.
pub struct Collection<'a, Cn, Cl> {
connection: &'a Cn,
_phantom: PhantomData<Cl>, // allows for extension traits to be written for collections of specific types
Expand All @@ -65,26 +65,26 @@ where
Cn: Connection<'a>,
Cl: schema::Collection,
{
/// create a new instance using `connection`
/// Creates a new instance using `connection`.
pub fn new(connection: &'a Cn) -> Self {
Self {
connection,
_phantom: PhantomData::default(),
}
}

/// add a new `Document<Cl>` with the contents `item`
/// Adds a new `Document<Cl>` with the contents `item`.
pub async fn push<S: Serialize + Sync>(&self, item: &S) -> Result<Header, crate::Error> {
let contents = serde_cbor::to_vec(item)?;
Ok(self.connection.insert::<Cl>(contents).await?)
}

/// add a new `Document<Cl>` with the contents `item`
/// Adds a new `Document<Cl>` with the contents `item`.
pub async fn update(&self, doc: &mut Document<'_>) -> Result<(), crate::Error> {
Ok(self.connection.update(doc).await?)
}

/// retrieve a `Document<Cl>` with `id` from the connection
/// Retrieves a `Document<Cl>` with `id` from the connection.
pub async fn get(&self, id: Uuid) -> Result<Option<Document<'static>>, Error> {
self.connection.get::<Cl>(id).await
}
Expand Down
41 changes: 21 additions & 20 deletions core/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,33 @@ use crate::schema::{collection, map, Map};
mod revision;
pub use revision::Revision;

/// the header of a `Document`
/// The header of a `Document`.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Header {
/// the id of the Document. Unique across the collection `C`
/// The id of the Document. Unique across the collection `C`
pub id: Uuid,

/// the revision of the stored document.
/// The revision of the stored document.
pub revision: Revision,
}

/// a struct representing a document in the database
/// Contains a serialized document in the database.
#[derive(Serialize, Deserialize, Debug)]
pub struct Document<'a> {
/// the `Id` of the `Collection` this document belongs to
/// The `Id` of the `Collection` this document belongs to.
pub collection: collection::Id,

/// the header of the document, which contains the id and `Revision`
/// The header of the document, which contains the id and `Revision`.
#[serde(borrow)]
pub header: Cow<'a, Header>,

/// the serialized bytes of the stored item
/// The serialized bytes of the stored item.
#[serde(borrow)]
pub contents: Cow<'a, [u8]>,
}

impl<'a> Document<'a> {
/// create a new document with `contents`
/// Creates a new document with `contents`.
#[must_use]
pub fn new(contents: Cow<'a, [u8]>, collection: collection::Id) -> Self {
let revision = Revision::new(&contents);
Expand All @@ -48,7 +48,7 @@ impl<'a> Document<'a> {
}
}

/// create a new document with serialized bytes from `contents`
/// Creates a new document with serialized bytes from `contents`.
pub fn with_contents<S: Serialize>(
contents: &S,
collection: collection::Id,
Expand All @@ -57,21 +57,22 @@ impl<'a> Document<'a> {
Ok(Self::new(contents, collection))
}

/// retrieves `contents` through deserialization into the type `D`
/// Retrieves `contents` through deserialization into the type `D`.
pub fn contents<D: Deserialize<'a>>(&'a self) -> Result<D, serde_cbor::Error> {
serde_cbor::from_slice(&self.contents)
}

/// serializes and stores `contents` into this document
/// Serializes and stores `contents` into this document.
pub fn set_contents<S: Serialize>(&mut self, contents: &S) -> Result<(), serde_cbor::Error> {
self.contents = Cow::from(serde_cbor::to_vec(contents)?);
Ok(())
}

/// create a new revision. **WARNING:** This normally should not be used
/// outside of implementing a backend for `PliantDB`. To update a document,
/// use `set_contents()` and send the document with the existing `Revision`
/// information.
/// Creates a new revision.
///
/// **WARNING: This normally should not be used** outside of implementing a
/// backend for `PliantDB`. To update a document, use `set_contents()` and
/// send the document with the existing `Revision` information.
#[must_use]
pub fn create_new_revision(&self, contents: Cow<'a, [u8]>) -> Option<Self> {
self.header
Expand All @@ -87,25 +88,25 @@ impl<'a> Document<'a> {
})
}

/// create a `Map` result with an empty key and value
/// Creates a `Map` result with an empty key and value.
#[must_use]
pub fn emit(&self) -> Map<'static, (), ()> {
self.emit_key_and_value((), ())
}

/// create a `Map` result with a `key` and an empty value
/// Creates a `Map` result with a `key` and an empty value.
#[must_use]
pub fn emit_key<'k, Key: map::Key<'k>>(&self, key: Key) -> Map<'k, Key, ()> {
self.emit_key_and_value(key, ())
}

/// create a `Map` result with `value` and an empty key
/// Creates a `Map` result with `value` and an empty key.
#[must_use]
pub fn emit_value<Value: Serialize>(&self, value: Value) -> Map<'static, (), Value> {
self.emit_key_and_value((), value)
}

/// create a `Map` result with a `key` and `value`
/// Creates a `Map` result with a `key` and `value`.
#[must_use]
pub fn emit_key_and_value<'k, Key: map::Key<'k>, Value: Serialize>(
&self,
Expand All @@ -115,7 +116,7 @@ impl<'a> Document<'a> {
Map::new(self.header.id, key, value)
}

/// clone the document's data so that it's no longer borrowed in the original lifetime `'a`
/// Clone the document's data so that it's no longer borrowed in the original lifetime `'a`.
#[must_use]
pub fn to_owned(&self) -> Document<'static> {
Document::<'static> {
Expand Down
8 changes: 4 additions & 4 deletions core/src/document/revision.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};

/// a struct containing information about a `Document`'s revision history
/// Information about a `Document`'s revision history.
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Revision {
/// The current revision id of the document. This value is sequentially incremented on each document update.
Expand All @@ -12,7 +12,7 @@ pub struct Revision {
}

impl Revision {
/// creates the first revision for a document with the SHA256 digest of the passed bytes
/// Creates the first revision for a document with the SHA256 digest of the passed bytes.
#[must_use]
pub fn new(contents: &[u8]) -> Self {
Self {
Expand All @@ -21,11 +21,11 @@ impl Revision {
}
}

/// creates the next revision in sequence with an updated digest. If the digest doesn't change, None is returned.
/// Creates the next revision in sequence with an updated digest. If the digest doesn't change, None is returned.
///
/// # Panics
///
/// Panics if `id` overflows
/// Panics if `id` overflows.
#[must_use]
pub fn next_revision(&self, new_contents: &[u8]) -> Option<Self> {
let sha256 = digest(new_contents);
Expand Down
8 changes: 4 additions & 4 deletions core/src/schema/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};

use crate::schema::Schema;

/// a unique collection id. Choose collection names that aren't likely to
/// A unique collection id. Choose collection names that aren't likely to
/// conflict with others, so that if someone mixes collections from multiple
/// authors in a single database.
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
Expand All @@ -28,11 +28,11 @@ impl Display for Id {
}
}

/// a namespaced collection of `Document<Self>` items and views
/// A namespaced collection of `Document<Self>` items and views.
pub trait Collection: Send + Sync {
/// the `Id` of this collection
/// The `Id` of this collection.
fn id() -> Id;

/// implementors define all of their `View`s in `schema`
/// Defines all `View`s in this collection in `schema`.
fn define_views(schema: &mut Schema);
}
12 changes: 6 additions & 6 deletions core/src/schema/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,36 @@ use crate::schema::{
View,
};

/// a trait that defines a group of collections that are stored into a single database
/// Defines a group of collections that are stored into a single database.
pub trait Database: Send + Sync {
/// implementors must define their `Collection`s in `schema`
/// Defines the `Collection`s into `schema`
fn define_collections(schema: &mut Schema);
}

trait ThreadsafeAny: Any + Send + Sync {}

impl<T> ThreadsafeAny for T where T: Any + Send + Sync {}

/// a collection of defined collections and views
/// A collection of defined collections and views.
#[derive(Default)]
pub struct Schema {
collections: HashMap<TypeId, collection::Id>,
views: HashMap<TypeId, Cow<'static, str>>,
}

impl Schema {
/// adds the collection `C` and its views
/// Adds the collection `C` and its views.
pub fn define_collection<C: Collection + 'static>(&mut self) {
self.collections.insert(TypeId::of::<C>(), C::id());
C::define_views(self)
}

/// adds the view `V`
/// Adds the view `V`.
pub fn define_view<'k, V: View<'k> + 'static>(&mut self) {
self.views.insert(TypeId::of::<V>(), V::name());
}

/// returns true if this schema contains the collection `C`
/// Returns `true` if this schema contains the collection `C`.
#[must_use]
pub fn contains<C: Collection + 'static>(&self) -> bool {
self.collections.contains_key(&TypeId::of::<C>())
Expand Down
4 changes: 2 additions & 2 deletions core/src/schema/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// types for defining a `Collection`
/// Types for defining a `Collection`.
pub mod collection;
mod database;
/// types for defining map/reduce-powered `View`s
/// Types for defining map/reduce-powered `View`s.
pub mod view;

pub use self::{collection::*, database::*, view::*};
34 changes: 19 additions & 15 deletions core/src/schema/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,55 @@ use serde::{Deserialize, Serialize};

use crate::document::Document;

/// types for defining a `Map` within a `View`
/// Types for defining a `Map` within a `View`.
pub mod map;
pub use map::{Key, Map};

/// errors that arise when interacting with views
/// Errors that arise when interacting with views.
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// an error occurred while serializing or deserializing
/// An error occurred while serializing or deserializing.
#[error("error deserializing document {0}")]
SerializationError(#[from] serde_cbor::Error),

/// returned when
/// Returned when the reduce() function is unimplemented.
#[error("reduce is unimplemented")]
ReduceUnimplemented,
}

/// a type alias for the result of `View::map()`
/// A type alias for the result of `View::map()`.
pub type MapResult<'k, K = (), V = ()> = Result<Option<Map<'k, K, V>>, Error>;

/// a map/reduce powered indexing and aggregation schema
/// A map/reduce powered indexing and aggregation schema.
///
/// inspired by [`CouchDB`'s view system](https://docs.couchdb.org/en/stable/ddocs/views/index.html)
/// Inspired by [`CouchDB`'s view
/// system](https://docs.couchdb.org/en/stable/ddocs/views/index.html)
///
/// This implementation is under active development, our own docs explaining our
/// implementation will be written as things are solidified.
// TODO write our own view docs
pub trait View<'k> {
/// the key for this view.
/// The key for this view.
type MapKey: Key<'k> + 'static;

/// an associated type that can be stored with each entry in the view
/// An associated type that can be stored with each entry in the view.
type MapValue: Serialize + for<'de> Deserialize<'de>;

/// when implementing reduce(), this is the returned type
/// When implementing reduce(), this is the returned type.
type Reduce: Serialize + for<'de> Deserialize<'de>;

/// the version of the view. Changing this value will cause indexes to be rebuilt.
/// The version of the view. Changing this value will cause indexes to be rebuilt.
fn version() -> usize;

/// the name of the view. Must be unique per collection.
/// The name of the view. Must be unique per collection.
fn name() -> Cow<'static, str>;

/// the map function for this view. This function is responsible for
/// The map function for this view. This function is responsible for
/// emitting entries for any documents that should be contained in this
/// View. If None is returned, the View will not include the document.
fn map(document: &Document<'_>) -> MapResult<'k, Self::MapKey, Self::MapValue>;

/// the reduce function for this view. If `Err(Error::ReduceUnimplemented)`
/// The reduce function for this view. If `Err(Error::ReduceUnimplemented)`
/// is returned, queries that ask for a reduce operation will return an
/// error. See [`CouchDB`'s Reduce/Rereduce
/// documentation](https://docs.couchdb.org/en/stable/ddocs/views/intro.html#reduce-rereduce)
Expand All @@ -62,7 +66,7 @@ pub trait View<'k> {
}
}

/// an enum representing either an owned value or a borrowed value. Functionally
/// Represents either an owned value or a borrowed value. Functionally
/// equivalent to `std::borrow::Cow` except this type doesn't require the
/// wrapped type to implement `Clone`.
pub enum SerializableValue<'a, T: Serialize> {
Expand Down
Loading

0 comments on commit a2a0e32

Please sign in to comment.