tags/
tags.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use hdk::prelude::*;
use tags_integrity::*;

use crate::utils::{create_link_relaxed, ensure_relaxed};

fn all_tags_path() -> ExternResult<TypedPath> {
    Path::from(format!("tags")).typed(LinkTypes::TagsPath)
}

fn tag_path(tag: String) -> ExternResult<TypedPath> {
    Path::from(format!("tags.{tag}")).typed(LinkTypes::TagsPath)
}

#[hdk_extern]
pub fn tag_path_hash(tag: String) -> ExternResult<EntryHash> {
    tag_path(tag)?.path_entry_hash()
}

#[hdk_extern]
pub fn get_all_tags() -> ExternResult<Vec<Link>> {
    let path = all_tags_path()?;
    get_links(GetLinksInputBuilder::try_new(path.path_entry_hash()?, LinkTypes::TagsPath)?.build())
}

#[derive(Serialize, Deserialize, Debug)]
pub struct AddTagInput {
    tag: String,
    hash: AnyDhtHash,
}

#[hdk_extern]
pub fn add_tag(input: AddTagInput) -> ExternResult<()> {
    let path = tag_path(input.tag.clone())?;
    ensure_relaxed(&path)?;
    create_link_relaxed(
        input.hash.clone(),
        path.path_entry_hash()?,
        LinkTypes::TaggedToTags,
        input.tag.clone(),
    )?;
    create_link_relaxed(
        path.path_entry_hash()?,
        input.hash,
        LinkTypes::TagToTaggeds,
        input.tag.clone(),
    )?;
    Ok(())
}

#[hdk_extern]
pub fn get_tags_for_tagged(hash: AnyDhtHash) -> ExternResult<Vec<Link>> {
    get_links(GetLinksInputBuilder::try_new(hash, LinkTypes::TaggedToTags)?.build())
}

#[hdk_extern]
pub fn get_taggeds_for_tag(tag: String) -> ExternResult<Vec<Link>> {
    let path = tag_path(tag)?;
    get_links(
        GetLinksInputBuilder::try_new(path.path_entry_hash()?, LinkTypes::TagToTaggeds)?.build(),
    )
}

#[derive(Serialize, Deserialize, Debug)]
pub struct RemoveTag {
    pub tag: String,
    pub hash: AnyDhtHash,
}

#[hdk_extern]
pub fn remove_tag(input: RemoveTag) -> ExternResult<()> {
    let path = tag_path(input.tag.clone())?;
    let links = get_links(
        GetLinksInputBuilder::try_new(path.path_entry_hash()?.clone(), LinkTypes::TagToTaggeds)?
            .build(),
    )?;
    for link in links {
        if link.target.clone().into_hash() == input.hash.clone().into_hash().into() {
            delete_link(link.create_link_hash)?;
        }
    }
    let links = get_links(
        GetLinksInputBuilder::try_new(input.hash.clone(), LinkTypes::TaggedToTags)?.build(),
    )?;
    for link in links {
        if link
            .target
            .clone()
            .into_entry_hash()
            .ok_or(wasm_error!(WasmErrorInner::Guest(
                "No entry hash associated with link".to_string()
            )))?
            == path.path_entry_hash()?.clone().into()
        {
            delete_link(link.create_link_hash)?;
        }
    }
    Ok(())
}