object_store/tags.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use url::form_urlencoded::Serializer;
19
20/// A collection of key value pairs used to annotate objects
21///
22/// <https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-tagging.html>
23/// <https://learn.microsoft.com/en-us/rest/api/storageservices/set-blob-tags>
24#[derive(Debug, Clone, Default, Eq, PartialEq)]
25pub struct TagSet(String);
26
27impl TagSet {
28 /// Append a key value pair to this [`TagSet`]
29 ///
30 /// Stores have different restrictions on what characters are permitted,
31 /// for portability it is recommended applications use no more than 10 tags,
32 /// and stick to alphanumeric characters, and `+ - = . _ : /`
33 ///
34 /// <https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html>
35 /// <https://learn.microsoft.com/en-us/rest/api/storageservices/set-blob-tags?tabs=azure-ad#request-body>
36 pub fn push(&mut self, key: &str, value: &str) {
37 Serializer::new(&mut self.0).append_pair(key, value);
38 }
39
40 /// Return this [`TagSet`] as a URL-encoded string
41 pub fn encoded(&self) -> &str {
42 &self.0
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn test_tag_set() {
52 let mut set = TagSet::default();
53 set.push("test/foo", "value sdlks");
54 set.push("foo", " sdf _ /+./sd");
55 assert_eq!(
56 set.encoded(),
57 "test%2Ffoo=value+sdlks&foo=+sdf+_+%2F%2B.%2Fsd"
58 );
59 }
60}