Lines
76.92 %
Functions
23.54 %
Branches
100 %
use arc_bytes::serde::Bytes;
use derive_where::derive_where;
use schema::SchemaName;
use serde::{Deserialize, Serialize};
use crate::{
connection::{AccessPolicy, Authenticated, Database, QueryKey, Range, Sort},
document::{DocumentId, OwnedDocument},
keyvalue::{KeyOperation, Output},
schema::{
self,
view::map::{self},
CollectionName, NamedReference, ViewName,
},
transaction::{Executed, OperationResult, Transaction},
};
/// The current protocol version.
pub const CURRENT_PROTOCOL_VERSION: &str = "bonsai/pre/0";
/// A payload with an associated id.
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct Payload<T> {
/// The unique id for this payload.
pub id: Option<u32>,
/// The wrapped payload.
pub wrapped: T,
}
/// A request made to a server.
#[derive(Clone, Deserialize, Serialize)]
#[derive_where(Debug)]
#[cfg_attr(feature = "actionable-traits", derive(actionable::Actionable))]
pub enum Request<T> {
/// A server-related request.
#[cfg_attr(feature = "actionable-traits", actionable(protection = "none"))]
Server(ServerRequest),
/// A database-related request.
Database {
/// The name of the database.
database: String,
/// The request made to the database.
request: DatabaseRequest,
#[cfg_attr(
feature = "actionable-traits",
actionable(protection = "none", subaction)
)]
#[derive_where(skip_inner)]
Api(T),
pub enum ServerRequest {
/// Creates a database.
#[cfg_attr(feature = "actionable-traits", actionable(protection = "simple"))]
CreateDatabase {
/// The database to create.
database: Database,
/// Only attempts to create the database if it doesn't already exist.
only_if_needed: bool,
/// Deletes the database named `name`
DeleteDatabase {
/// The name of the database to delete.
name: String,
/// Lists all databases.
ListDatabases,
/// Lists available schemas.
ListAvailableSchemas,
/// Creates a user.
CreateUser {
/// The unique username of the user to create.
username: String,
/// Set's a user's password.
#[cfg(feature = "password-hashing")]
SetUserPassword {
/// The username or id of the user.
user: NamedReference<'static, u64>,
/// The user's new password.
password: crate::connection::SensitiveString,
/// Authenticate as a user.
#[cfg_attr(feature = "actionable-traits", actionable(protection = "custom"))]
Authenticate {
/// The method of authentication.
authentication: crate::connection::Authentication,
/// Alter's a user's membership in a permission group.
AlterUserPermissionGroupMembership {
/// The name or id of the group.
group: NamedReference<'static, u64>,
/// Whether the user should be in the group.
should_be_member: bool,
/// Alter's a user's role
AlterUserRoleMembership {
/// The name or id of the role.
role: NamedReference<'static, u64>,
/// Whether the user should have the role.
pub enum DatabaseRequest {
/// Retrieve a single document.
Get {
/// The collection of the document.
collection: CollectionName,
/// The id of the document.
id: DocumentId,
/// Retrieve multiple documents.
GetMultiple {
/// The collection of the documents.
/// The ids of the documents.
ids: Vec<DocumentId>,
List {
/// The range of ids to list.
ids: Range<DocumentId>,
/// The order for the query into the collection.
order: Sort,
/// The maximum number of results to return.
limit: Option<usize>,
/// Queries a view.
Query {
/// The name of the view.
view: ViewName,
/// The filter for the view.
key: Option<QueryKey<Bytes>>,
/// The order for the query into the view.
/// The access policy for the query.
access_policy: AccessPolicy,
/// If true, [`DatabaseResponse::ViewMappingsWithDocs`] will be
/// returned. If false, [`DatabaseResponse::ViewMappings`] will be
/// returned.
with_docs: bool,
/// Reduces a view.
Reduce {
/// Whether to return a single value or values grouped by unique key. If
/// true, [`DatabaseResponse::ViewGroupedReduction`] will be returned.
/// If false, [`DatabaseResponse::ViewReduction`] is returned.
grouped: bool,
/// Deletes the associated documents resulting from the view query.
DeleteDocs {
/// Applies a transaction.
ApplyTransaction {
/// The trasnaction to apply.
transaction: Transaction,
/// Lists executed transactions.
ListExecutedTransactions {
/// The starting transaction id.
starting_id: Option<u64>,
/// The maximum number of results.
result_limit: Option<usize>,
/// Queries the last transaction id.
LastTransactionId,
/// Creates a `PubSub` [`Subscriber`](crate::pubsub::Subscriber)
CreateSubscriber,
/// Publishes `payload` to all subscribers of `topic`.
Publish {
/// The topics to publish to.
topic: String,
/// The payload to publish.
payload: Bytes,
/// Publishes `payload` to all subscribers of all `topics`.
PublishToAll {
topics: Vec<String>,
/// Subscribes `subscriber_id` to messages for `topic`.
SubscribeTo {
/// The id of the [`Subscriber`](crate::pubsub::Subscriber).
subscriber_id: u64,
/// The topic to subscribe to.
/// Unsubscribes `subscriber_id` from messages for `topic`.
UnsubscribeFrom {
/// The topic to unsubscribe from.
/// Unregisters the subscriber.
UnregisterSubscriber {
/// Excutes a key-value store operation.
ExecuteKeyOperation(KeyOperation),
/// Compacts the collection.
CompactCollection {
/// The name of the collection to compact.
name: CollectionName,
/// Compacts the key-value store.
CompactKeyValueStore,
/// Compacts the entire database.
Compact,
/// A response from a server.
#[derive(Clone, Serialize, Deserialize)]
pub enum Response<T> {
/// A request succeded but provided no output.
Ok,
/// A response to a [`ServerRequest`].
Server(ServerResponse),
/// A response to a [`DatabaseRequest`].
Database(DatabaseResponse),
/// A response to an Api request.
/// An error occurred processing a request.
Error(crate::Error),
#[derive(Clone, Serialize, Deserialize, Debug)]
pub enum ServerResponse {
/// A database with `name` was successfully created.
DatabaseCreated {
/// The name of the database to create.
/// A database with `name` was successfully removed.
DatabaseDeleted {
/// The name of the database to remove.
/// A list of available databases.
Databases(Vec<Database>),
/// A list of availble schemas.
AvailableSchemas(Vec<SchemaName>),
/// A user was created.
UserCreated {
/// The id of the user created.
id: u64,
/// Successfully authenticated.
Authenticated(Authenticated),
pub enum DatabaseResponse {
/// One or more documents.
Documents(Vec<OwnedDocument>),
/// A number of documents were deleted.
DocumentsDeleted(u64),
/// Results of [`DatabaseRequest::ApplyTransaction`].
TransactionResults(Vec<OperationResult>),
/// Results of [`DatabaseRequest::Query`] when `with_docs` is false.
ViewMappings(Vec<map::Serialized>),
/// Results of [`DatabaseRequest::Query`] when `with_docs` is true.
ViewMappingsWithDocs(map::MappedSerializedDocuments),
/// Result of [`DatabaseRequest::Reduce`] when `grouped` is false.
ViewReduction(Bytes),
/// Result of [`DatabaseRequest::Reduce`] when `grouped` is true.
ViewGroupedReduction(Vec<map::MappedSerializedValue>),
/// Results of [`DatabaseRequest::ListExecutedTransactions`].
ExecutedTransactions(Vec<Executed>),
/// Result of [`DatabaseRequest::LastTransactionId`].
LastTransactionId(Option<u64>),
/// A new `PubSub` subscriber was created.
SubscriberCreated {
/// The unique ID of the subscriber.
/// A PubSub message was received.
MessageReceived {
/// The ID of the subscriber receiving the message.
/// The topic the payload was received on.
/// The message payload.
/// Output from a [`KeyOperation`] being executed.
KvOutput(Output),
/// A networking error.
#[derive(Clone, thiserror::Error, Debug, Serialize, Deserialize)]
pub enum Error {
/// The server responded with a message that wasn't expected for the request
/// sent.
#[error("unexpected response: {0}")]
UnexpectedResponse(String),
/// The connection was interrupted.
#[error("unexpected disconnection")]
Disconnected,