Priorities
Book zome
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct Book {
name: String,
author: String,
genre: String,
blurb: String,
isbn: String,
book_owner: Address
}
create_book: {
inputs: |book: Book|,
outputs: |result: ZomeApiResult<Address>|,
handler: handle_create_book
}
get_book: {
inputs: |address: Address|,
outputs: |result: ZomeApiResult<GetEntryResult>|, // Another change request from guillem, this GetEntryResult type can be returned by using https://developer.holochain.org/api/latest/hdk/api/fn.get_entry_result.html
handler: handle_get_book
}
get_my_books: {
inputs: | |,
outputs: |result: ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>>|,
handler: handle_get_books
}
get_owner: {
inputs: |address: Address|,
outputs: |result: ZomeApiResult<Address>|,
handler: handle_get_owner
}
Loans zome
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct LoanRequest {
item_address: Address,
borrower_address: Address,
created_at: i64,
}
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct Loan {
item_address: Address,
borrower_address: Option<Address>,
started_at: Option<i64>
finished_at: Option<i64>
comment: Option<String>
return_by: Option<i64>
}
// Create a loan request entry
// Called by the person who wants to borrow
request_to_borrow(item_address: Address, created_at: i64): -> ZomeApiResult<Address>
get_my_loan_requests() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>>
// This assumes that the books zome has a way of getting all the items of an owner
get_item_loan_requests(item_address: Address) -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>>
// Create a loan entry
// Called by the person who owns the item
// Steps
// 1. Get the loan request
// 2. Get the loan entry
// 3. If the loan entry does not exist, create it only with item_address
// 4. Update the loan entry with the new information
// 5. Create a link from the borrower agent address to the address of the updated entry (not the original entry address)
// 6. Delete the loan request
create_loan(loan_request_address: Address, started_at: i64, return_by: i64) -> ZomeApiResult<Address>
// Remove a loan request
// Called by the person who owns the item
decline_loan(loan_request_address: Address) -> ZomeApiResult<()>
get_loan_history(item_address: Address) -> ZomeApiResult<Option<EntryHistory>>
get_loan_status(item_address: Address) -> ZomeApiResult<Option<Entry>>
// Has to be called by the borrower first and the by the lender
// If double signature, remove link between borrower agent address and loan
finish_loan(item_address: Address, finished_at: i64, comment: Option<String>) -> ZomeApiResult<()>
// Retrieve the loans throught the borrower->loans links
get_my_active_loans() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>>
Further implementations
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct Collection {
name: String,
}
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct User {
name: String,
street: String,
zip: String,
city: String,
country: String,
}
get_my_address: {
inputs: | |,
outputs: |result: JsonString|,
handler: handle_get_my_address
}
create_collection: {
inputs: |name: String|,
outputs: |result: JsonString|,
handler: handle_create_collection
}
create_user: {
inputs: |name: String, street: String, zip: String, city: String, country: String|,
outputs: |result: JsonString|,
handler: handle_create_user
}
get_user_data: {
inputs: |address: Address|,
outputs: |result: JsonString|,
handler: handle_get_user_data
}
add_book_to_collection: {
inputs: |book_address: Address, collection_address: Address|,
outputs: |result: JsonString|,
handler: handle_add_book_to_collection
}
get_books_in_collection: {
inputs: |collection_address: Address, tag: String|,
outputs: |result: JsonString|,
handler: handle_get_books_in_collection
}
get_collections_book_is_in: {
inputs: |book_address: Address, tag: String|,
outputs: |result: JsonString|,
handler: handle_get_collections_book_is_in
}
//retrieve all books linked to the anchor shelf
get_books: {
inputs: |shelf_address: Address, tag: String|,
outputs: |result: JsonString|,
handler: handle_get_books
}
get_owners: {
inputs: |book_address: Address, tag: String|,
outputs: |result: JsonString|,
handler: handle_get_owners
}
request_to_borrow: {
inputs: |borrower_address: Address, book_address: Address|,
outputs: |result: JsonString|,
handler: handle_request_to_borrow
}
get_requests_by_user: {
inputs: |borrower_address: Address|,
outputs: |result: JsonString|,
handler: handle_get_requests_by_user
}
get_book_requests: {
inputs: |book_address: Address|,
outputs: |result: JsonString|,
handler: handle_get_book_requests
}
create_loan: {
inputs: |book_address: Address, borrower_address: Address, return_by: String|,
outputs: |result: JsonString|,
handler: handle_create_loan
}
paste code here: zomes/books./lib.rs
use std::convert::TryFrom;
use hdk::{
utils,
entry_definition::ValidatingEntryType,
error::{ZomeApiResult, ZomeApiError},
holochain_persistence_api::{
cas::content::{AddressableContent, Address},
},
holochain_json_api::{
error::JsonError, json::JsonString,
},
holochain_core_types::{
dna::entry_types::Sharing,
validation::EntryValidationData,
entry::Entry,
link::LinkMatch,
}
};
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
pub struct Book {
name: String,
author: String,
genre: String,
blurb: String,
isbn: String,
book_owner: Address
}
pub fn definition() -> ValidatingEntryType {
entry!(
name: "book",
description: "Represents a book as an item source of loan system",
sharing: Sharing::Public,
validation_package: || {
hdk::ValidationPackageDefinition::Entry
},
// link
validation: | validation_data: hdk::EntryValidationData<Book>| {
match validation_data {
EntryValidationData::Create{entry, validation_data: _} => {
let book = entry as Book;
if book.name.trim().is_empty() {
return Err("Name of the book can not be empty".into())
}
if book.author.trim().is_empty() {
return Err("Author of the book can not be empty".into())
}
if book.genre.trim().is_empty() {
return Err("Genre of the book can not be empty".into())
}
if book.name.trim().is_empty() {
return Err("ISBN of the book can not be empty".into())
}
// how to check Address
Ok(())
},
_ => {
Err("the entry is not the type of Book".into())
}
}
},
links: [
from!(
"%agent_id",
link_type: "owner_book",
validation_package: || {
hdk::ValidationPackageDefinition::ChainFull
},
validation: | validation_data: hdk::LinkValidationData | {
if let hdk::LinkValidationData::LinkAdd{link, ..} = validation_data {
if link.link.tag() == "muffins" {
Err("This is the one tag that is not allowed!".into())
} else {
Ok(())
}
} else {
Ok(())
}
}
)
]
)
}
/*************** lib/
#![feature(proc_macro_hygiene)]
#[macro_use]
extern crate hdk;
extern crate hdk_proc_macros;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[macro_use]
extern crate holochain_json_derive;
use std::convert::TryFrom;
//holochain_wasm_utils::api_serialization::get_entry::GetEntryOptions
use holochain_wasm_utils::*;
use hdk::{
entry_definition::ValidatingEntryType,
error::ZomeApiResult,
AGENT_ADDRESS
};
use hdk::holochain_core_types::{
entry::Entry,
dna::entry_types::Sharing,
};
use hdk::holochain_json_api::{
json::JsonString,
error::JsonError
};
use hdk::holochain_persistence_api::{
cas::content::Address
};
use hdk_proc_macros::zome;
mod book;
#[zome]
mod book_zome {
#[init]
fn init() {
Ok(())
}
#[validate_agent]
pub fn validate_agent(validation_data: EntryValidationData<AgentId>) {
Ok(())
}
#[entry_def]
fn book_entry_def() -> ValidatingEntryType {
book::definition();
}
#[zome_fn("hc_public")]
fn create_book(book:Book) -> ZomeApiResult<Address>{
let entry = Entry::App("book".into(),book.into());
let address = hdk::commit_entry(&entry)?;
Ok(address)
}
#[zome_fn("hc_public")]
fn get_book(address:Address) -> ZomeApiResult<GetEntryResult> {
hdk::get_entry_result(address, GetEntryOptions::default())
}
#[zome_fn("hc_public")]
fn get_my_books() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>> {
hdk::get_links_result(AgentId, LinkMatch::Exactly("owner_book"), LinkMatch::Any, GetLinksOptions::default(), GetEntryOptions::default())
}
#[zome_fn("hc_public")]
fn get_owner(address:Address) -> ZomeApiResult<Address> {
Ok(hdk::get_entry_result(address, GetEntryOptions::default()).Address)
}
}
#![feature(proc_macro_hygiene)]
#[macro_use]
extern crate hdk;
extern crate hdk_proc_macros;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[macro_use]
extern crate holochain_json_derive;
use hdk::{
entry_definition::ValidatingEntryType,
error::ZomeApiResult,
};
use hdk::holochain_core_types::{
entry::Entry,
dna::entry_types::Sharing,
};
use hdk::holochain_json_api::{
json::JsonString,
error::JsonError
};
use hdk::holochain_persistence_api::{
cas::content::Address
};
use hdk_proc_macros::zome;
// see https://developer.holochain.org/api/latest/hdk/ for info on using the hdk library
// This is a sample zome that defines an entry type "MyEntry" that can be committed to the
// agent's chain via the exposed function create_my_entry
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct LoanRequest {
item_address: Address,
borrower_address: Address,
}
#[derive(Serialize, Deserialize, Debug, DefaultJson)]
struct Loan {
item_address: Address,
borrower_address: Address,
return_by: i64
}
#[zome]
mod loans {
#[init]
fn init() {
Ok(())
}
#[validate_agent]
pub fn validate_agent(validation_data: EntryValidationData<AgentId>) {
Ok(())
}
#[entry_def]
fn loan_request_def() -> ValidatingEntryType {
entry!(
name: "loan_request",
description: "a request that a user has created when wanting to borrow someones item",
sharing: Sharing::Public,
validation_package: || {
hdk::ValidationPackageDefinition::Entry
},
validation: | _validation_data: hdk::EntryValidationData<MyEntry>| {
Ok(())
},
links: [
to!(
"loan_request",
link_type: "owner_of_item_requested",
validation_package: || {
hdk::ValidationPackageDefinition::ChainFull
},
validation: | _validation_data: hdk::LinkValidationData | {
Ok(())
}
)]
)
}
#[entry_def]
fn loan_def() -> ValidatingEntryType {
entry!(
name: "loan",
description: "a loan entry created when a request to borrow is accepted by the owner",
sharing: Sharing::Public,
validation_package: || {
hdk::ValidationPackageDefinition::Entry
},
validation: | _validation_data: hdk::EntryValidationData<MyEntry>| {
Ok(())
}
),
to!(
"loan",
link_type: "owner_of_item_loaned",
validation_package: || {
hdk::ValidationPackageDefinition::ChainFull
},
validation: | _validation_data: hdk::LinkValidationData | {
Ok(())
}
)]
}
#[zome_fn("hc_public")]
fn request_to_borrow(loan_request: LoanRequest) -> ZomeApiResult<Address> {
//creating the request entry
let entry = Entry::App("loan_request".into(), entry.into());
let address = hdk::commit_entry(&entry)?;
// call get_owner function from book zome
// create a link from owner_of_item to loan_request
Ok(address)
}
#[zome_fn("hc_public")]
fn get_loan_requests() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>> {
//get all loan requests for the user
//hdk::get_entry(&address)
}
#[zome_fn("hc_public")]
fn create_loan(loan_request_address: Address, return_by: i64) -> ZomeApiResult<Address> {
//create a loan entry
let entry = Entry::App("loan".into(), entry.into());
let address = hdk::commit_entry(&entry)?;
//create a link to the owner of the loan (and also one to the borrower?)
Ok(address)
}
#[zome_fn("hc_public")]
fn decline_loan(loan_request_address: Address) -> ZomeApiResult<Address> {
//mark request as deleted?
ok()
}
#[zome_fn("hc_public")]
fn get_my_loans() -> ZomeApiResult<Vec<ZomeApiResult<GetEntryResult>>> {
//get a vector of my loans based on my agent address and links
ok()
}
}