Skip to main content

edc_web_components/models/
asset_item.rs

1use crate::models::dataset_extra_fields::DatasetExtraFields;
2use crate::models::{Creator, DataspaceDataset, Thumbnail};
3use edc_connector_client::types::asset::Asset;
4use edc_connector_client::types::catalog::Dataset;
5use edc_connector_client::types::data_address::DataAddress;
6use edc_connector_client::types::properties::{Properties, PropertyValue};
7
8#[derive(Clone, Debug, PartialEq)]
9pub struct AssetItem {
10  pub id: String,
11  pub name: String,
12  pub version: Option<semver::Version>,
13  pub description: Option<String>,
14  pub creator: Option<Creator>,
15  pub thumbnail: Option<Thumbnail>,
16  pub keywords: Vec<String>,
17  pub landing_page: Option<String>,
18  pub dcterm_types: Vec<String>,
19  pub base_url: String,
20  pub proxy_path: bool,
21  pub proxy_query_params: bool,
22  pub proxy_method: bool,
23  pub proxy_body: bool,
24}
25
26impl AssetItem {
27  pub fn is_filtered(&self, search: &Option<String>, dcterm_types: &[String]) -> bool {
28    let text_content = format!(
29      "{} {} {} {}",
30      self.name.to_lowercase(),
31      self.description.clone().unwrap_or_default().to_lowercase(),
32      self.keywords.join(" ").to_lowercase(),
33      self
34        .creator
35        .clone()
36        .map(|creator| creator.name.unwrap_or_default().to_lowercase())
37        .unwrap_or_default()
38    );
39
40    if !dcterm_types.is_empty() {
41      if self
42        .dcterm_types
43        .iter()
44        .any(|dcterm_type| dcterm_types.contains(dcterm_type))
45      {
46        if let Some(search) = &search {
47          text_content.contains(&search.to_lowercase())
48        } else {
49          true
50        }
51      } else {
52        false
53      }
54    } else {
55      if let Some(search) = &search {
56        text_content.contains(&search.to_lowercase())
57      } else {
58        true
59      }
60    }
61  }
62}
63
64impl From<Asset> for AssetItem {
65  fn from(asset: Asset) -> Self {
66    let id = asset.id().to_string();
67    let name = get_property(asset.properties(), "name");
68    let description = asset
69      .properties()
70      .get::<String>("http://www.w3.org/2000/01/rdf-schema#comment")
71      .unwrap_or_default();
72
73    let version = asset
74      .properties()
75      .get::<String>("http://www.w3.org/ns/dcat#version")
76      .unwrap_or_default()
77      .and_then(|version| semver::Version::parse(version.as_str()).ok());
78
79    let creator = asset
80      .properties()
81      .get_raw("http://purl.org/dc/terms/creator")
82      .and_then(|property_value| serde_json::from_value::<Creator>(property_value.0.clone()).ok());
83
84    let thumbnail = asset
85      .properties()
86      .get_raw("http://xmlns.com/foaf/0.1/thumbnail")
87      .and_then(|property_value| {
88        serde_json::from_value::<Thumbnail>(property_value.0.clone()).ok()
89      });
90
91    let keywords = asset
92      .properties()
93      .get_raw("http://www.w3.org/ns/dcat#keyword")
94      .and_then(|property_value| {
95        serde_json::from_value::<Vec<String>>(property_value.0.clone()).ok()
96      })
97      .unwrap_or_default();
98
99    let landing_page = asset
100      .properties()
101      .get::<String>("http://www.w3.org/ns/dcat#landingPage")
102      .unwrap_or_default();
103
104    let dcterm_types = asset
105      .properties()
106      .get_raw("http://purl.org/dc/terms/type")
107      .and_then(|property_value| {
108        if let Ok(value) = PropertyValue::try_from(property_value) {
109          Some(vec![value])
110        } else {
111          serde_json::from_value::<Vec<String>>(property_value.0.clone()).ok()
112        }
113      })
114      .unwrap_or_default();
115
116    let base_url = asset
117      .data_address()
118      .property("baseUrl")
119      .unwrap_or_default()
120      .unwrap_or_default();
121
122    let proxy_path = get_boolean_property(asset.data_address(), "proxyPath");
123    let proxy_query_params = get_boolean_property(asset.data_address(), "proxyQueryParams");
124    let proxy_method = get_boolean_property(asset.data_address(), "proxyMethod");
125    let proxy_body = get_boolean_property(asset.data_address(), "proxyBody");
126
127    AssetItem {
128      id,
129      name,
130      version,
131      description,
132      creator,
133      thumbnail,
134      keywords,
135      landing_page,
136      dcterm_types,
137      base_url,
138      proxy_path,
139      proxy_query_params,
140      proxy_method,
141      proxy_body,
142    }
143  }
144}
145
146impl From<edc_federated_catalog_client::models::Dataset> for AssetItem {
147  fn from(dataset: edc_federated_catalog_client::models::Dataset) -> Self {
148    Self {
149      id: dataset.id.clone(),
150      name: dataset.name,
151      version: dataset
152        .version
153        .and_then(|version| semver::Version::parse(&version).ok()),
154      description: dataset.description,
155      creator: dataset.creator.map(|creator| Creator {
156        name: Some(creator.name),
157        thumbnail: Some(Thumbnail {
158          resource: Some(creator.thumbnail.resource),
159        }),
160      }),
161      thumbnail: dataset.thumbnail.map(|thumbnail| Thumbnail {
162        resource: Some(thumbnail.resource),
163      }),
164      keywords: dataset.keywords,
165      landing_page: dataset.landing_page,
166      dcterm_types: dataset.dcterm_types,
167      base_url: "".to_string(),
168      proxy_path: false,
169      proxy_query_params: false,
170      proxy_method: false,
171      proxy_body: false,
172    }
173  }
174}
175
176impl From<&Dataset<DatasetExtraFields>> for AssetItem {
177  fn from(dataset: &Dataset<DatasetExtraFields>) -> Self {
178    let id = dataset.id().to_string();
179    let extra = &dataset.extra;
180
181    Self {
182      id,
183      name: extra.name.clone(),
184      version: extra
185        .version
186        .as_ref()
187        .and_then(|version| semver::Version::parse(version).ok()),
188      description: extra.description.to_owned(),
189      creator: extra.creator.as_ref().map(|creator| Creator {
190        name: Some(creator.name.to_owned()),
191        thumbnail: Some(Thumbnail {
192          resource: Some(creator.thumbnail.resource.to_owned()),
193        }),
194      }),
195      thumbnail: extra.thumbnail.as_ref().map(|thumbnail| Thumbnail {
196        resource: Some(thumbnail.resource.to_owned()),
197      }),
198      keywords: extra.keywords.clone(),
199      landing_page: extra.landing_page.clone(),
200      dcterm_types: extra.dcterm_types.clone(),
201      base_url: "".to_string(),
202      proxy_path: false,
203      proxy_query_params: false,
204      proxy_method: false,
205      proxy_body: false,
206    }
207  }
208}
209
210impl From<AssetItem> for DataspaceDataset {
211  fn from(asset_item: AssetItem) -> Self {
212    Self {
213      id: asset_item.id,
214      title: asset_item.name,
215      version: asset_item.version,
216      comment: asset_item.description,
217      thumbnail: asset_item.thumbnail,
218      creator: asset_item.creator,
219      keywords: asset_item.keywords,
220      dcterm_types: asset_item.dcterm_types,
221      policies: vec![],
222    }
223  }
224}
225
226fn get_property(properties: &Properties, name: &str) -> String {
227  properties
228    .get::<String>(name)
229    .unwrap_or_default()
230    .unwrap_or_default()
231}
232
233fn get_boolean_property(data_address: &DataAddress, name: &str) -> bool {
234  data_address
235    .property::<String>(name)
236    .unwrap_or_default()
237    .unwrap_or_default()
238    == "true"
239}