hdi/
link.rs

1use std::collections::HashMap;
2
3use holochain_integrity_types::LinkTypeFilter;
4use holochain_wasmer_guest::WasmError;
5
6use crate::prelude::*;
7
8#[cfg(doc)]
9pub mod examples;
10
11/// An extension to obtain a link type filter.
12///
13/// Allows for single link types as well as the full range of link types to be passed in.
14/// To include all link types, i. e. not filter out any link type, the full range operator `..`
15/// can be used: `get_links(base, .., None)`.
16///
17/// Refer to the `get_links` function in
18/// [this coordinator zome](https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/link/src/coordinator.rs)
19/// for several examples.
20pub trait LinkTypeFilterExt {
21    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError>;
22}
23
24impl LinkTypeFilterExt for core::ops::RangeFull {
25    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError> {
26        let out = zome_info()?.zome_types.links.dependencies().collect();
27        Ok(LinkTypeFilter::Dependencies(out))
28    }
29}
30
31impl LinkTypeFilterExt for LinkTypeFilter {
32    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError> {
33        Ok(self)
34    }
35}
36
37impl<T, E> LinkTypeFilterExt for Vec<T>
38where
39    T: TryInto<ScopedLinkType, Error = E>,
40    WasmError: From<E>,
41{
42    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError> {
43        // Collect into a 2d vector of where `LinkType`s are collected
44        // into their common `ZomeIndex`s.
45        let vec = self
46            .into_iter()
47            .try_fold(HashMap::new(), |mut map: HashMap<_, Vec<_>>, t| {
48                let scoped = TryInto::<ScopedLinkType>::try_into(t)?;
49                map.entry(scoped.zome_index)
50                    .or_default()
51                    .push(scoped.zome_type);
52                Ok(map)
53            })?
54            .into_iter()
55            .collect::<Vec<(_, Vec<_>)>>();
56
57        Ok(LinkTypeFilter::Types(vec))
58    }
59}
60
61impl<T, E, const N: usize> LinkTypeFilterExt for [T; N]
62where
63    T: TryInto<ScopedLinkType, Error = E>,
64    WasmError: From<E>,
65{
66    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError> {
67        self.into_iter()
68            .map(TryInto::<ScopedLinkType>::try_into)
69            .collect::<Result<Vec<_>, _>>()?
70            .try_into_filter()
71    }
72}
73
74impl<T, E, const N: usize> LinkTypeFilterExt for &[T; N]
75where
76    for<'a> &'a T: TryInto<ScopedLinkType, Error = E>,
77    WasmError: From<E>,
78{
79    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError> {
80        self.iter()
81            .map(TryInto::<ScopedLinkType>::try_into)
82            .collect::<Result<Vec<_>, _>>()?
83            .try_into_filter()
84    }
85}
86
87impl<T, E> LinkTypeFilterExt for &[T]
88where
89    for<'a> &'a T: TryInto<ScopedLinkType, Error = E>,
90    WasmError: From<E>,
91{
92    fn try_into_filter(self) -> Result<LinkTypeFilter, WasmError> {
93        self.iter()
94            .map(TryInto::<ScopedLinkType>::try_into)
95            .collect::<Result<Vec<_>, _>>()?
96            .try_into_filter()
97    }
98}