dynoxide/actions/
tag_resource.rs1use crate::actions::helpers;
2use crate::errors::{DynoxideError, Result};
3use crate::storage::Storage;
4use crate::types::Tag;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Default, Deserialize)]
8pub struct TagResourceRequest {
9 #[serde(rename = "ResourceArn", default)]
10 pub resource_arn: Option<String>,
11 #[serde(rename = "Tags", default)]
12 pub tags: Vec<Tag>,
13}
14
15#[derive(Debug, Default, Serialize)]
16pub struct TagResourceResponse {}
17
18pub fn execute(storage: &Storage, request: TagResourceRequest) -> Result<TagResourceResponse> {
19 let arn = request.resource_arn.as_deref().unwrap_or("");
20 if arn.is_empty() {
21 return Err(DynoxideError::ValidationException(
22 "Invalid TableArn".to_string(),
23 ));
24 }
25 let table_name = helpers::parse_table_name_from_arn(arn)?;
26
27 if request.tags.is_empty() {
29 return Err(DynoxideError::ValidationException(
30 "Atleast one Tag needs to be provided as Input.".to_string(),
31 ));
32 }
33 for tag in &request.tags {
34 validate_tag(tag)?;
35 }
36
37 if !storage.table_exists(table_name)? {
39 return Err(DynoxideError::ResourceNotFoundException(format!(
40 "Requested resource not found: ResourcArn: {arn} not found"
41 )));
42 }
43
44 storage.set_tags(table_name, &request.tags)?;
45
46 Ok(TagResourceResponse {})
47}
48
49fn validate_tag(tag: &Tag) -> Result<()> {
50 if tag.key.is_empty() || tag.key.len() > 128 {
51 return Err(DynoxideError::ValidationException(
52 "One or more parameter values were invalid: \
53 Tag key must be between 1 and 128 characters"
54 .to_string(),
55 ));
56 }
57 if tag.value.len() > 256 {
58 return Err(DynoxideError::ValidationException(
59 "One or more parameter values were invalid: \
60 Tag value must be between 0 and 256 characters"
61 .to_string(),
62 ));
63 }
64 Ok(())
65}