Skip to main content

ali_oss_rs/blocking/
symlink.rs

1//! Object symlink module
2
3use super::Client;
4use crate::symlink_common::{build_get_symlink_request, build_put_symlink_request, GetSymlinkOptions, PutSymlinkOptions, PutSymlinkResult};
5use crate::Result;
6
7pub trait ObjectSymlinkOperations {
8    /// Put a symlink object.
9    ///
10    /// `target_object_key` should be a full and valid object key.
11    ///
12    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/putsymlink>
13    fn put_symlink<S1, S2, S3>(
14        &self,
15        bucket_name: S1,
16        symlink_object_key: S2,
17        target_object_key: S3,
18        options: Option<PutSymlinkOptions>,
19    ) -> Result<PutSymlinkResult>
20    where
21        S1: AsRef<str>,
22        S2: AsRef<str>,
23        S3: AsRef<str>;
24
25    /// Get a symlink object. The returned string is the target object key
26    ///
27    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/getsymlink>
28    fn get_symlink<S1, S2>(&self, bucket_name: S1, symlink_object_key: S2, options: Option<GetSymlinkOptions>) -> Result<String>
29    where
30        S1: AsRef<str>,
31        S2: AsRef<str>;
32}
33
34impl ObjectSymlinkOperations for Client {
35    /// Put a symlink object.
36    ///
37    /// `target_object_key` should be a full and valid object key.
38    ///
39    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/putsymlink>
40    fn put_symlink<S1, S2, S3>(
41        &self,
42        bucket_name: S1,
43        symlink_object_key: S2,
44        target_object_key: S3,
45        options: Option<PutSymlinkOptions>,
46    ) -> Result<PutSymlinkResult>
47    where
48        S1: AsRef<str>,
49        S2: AsRef<str>,
50        S3: AsRef<str>,
51    {
52        let request = build_put_symlink_request(bucket_name.as_ref(), symlink_object_key.as_ref(), target_object_key.as_ref(), &options)?;
53        let (headers, _) = self.do_request::<()>(request)?;
54        Ok(headers.into())
55    }
56
57    /// Get a symlink object. The returned string is the target object key
58    ///
59    /// Official document: <https://help.aliyun.com/zh/oss/developer-reference/getsymlink>
60    fn get_symlink<S1, S2>(&self, bucket_name: S1, symlink_object_key: S2, options: Option<GetSymlinkOptions>) -> Result<String>
61    where
62        S1: AsRef<str>,
63        S2: AsRef<str>,
64    {
65        let request = build_get_symlink_request(bucket_name.as_ref(), symlink_object_key.as_ref(), &options)?;
66        let (headers, _) = self.do_request::<()>(request)?;
67        let object_key = headers.get("x-oss-symlink-target").unwrap_or(&String::new()).to_string();
68
69        Ok(urlencoding::decode(&object_key)?.to_string())
70    }
71}
72
73#[cfg(all(test, feature = "blocking"))]
74mod test_symlink_blocking {
75    use std::sync::Once;
76
77    use uuid::Uuid;
78
79    use crate::{
80        blocking::{object::ObjectOperations, symlink::ObjectSymlinkOperations},
81        object_common::{PutObjectApiResponse, PutObjectResult},
82        symlink_common::PutSymlinkOptionsBuilder,
83    };
84
85    use super::Client;
86
87    static INIT: Once = Once::new();
88
89    fn setup() {
90        INIT.call_once(|| {
91            simple_logger::init_with_level(log::Level::Debug).unwrap();
92            dotenvy::dotenv().unwrap();
93        });
94    }
95
96    #[test]
97    fn test_symlink_blocking() {
98        log::debug!("test symlink");
99        setup();
100
101        let client = Client::from_env();
102        let bucket_name = "yuanyq-2";
103        let object_key = format!("versioning-test/{}.webp", Uuid::new_v4());
104        let file_path = "/home/yuanyq/Pictures/test-7.webp";
105
106        let link_name = format!("versioning-test/{}-link.webp", Uuid::new_v4());
107
108        let response = client.put_object_from_file(bucket_name, &object_key, file_path, None);
109        assert!(response.is_ok());
110
111        let ret = response.unwrap();
112        let version_id = if let PutObjectResult::ApiResponse(PutObjectApiResponse {
113            request_id: _,
114            etag: _,
115            content_md5: _,
116            hash_crc64ecma: _,
117            version_id,
118        }) = ret
119        {
120            assert!(version_id.is_some());
121            version_id.clone().unwrap()
122        } else {
123            panic!("Unexpected response type");
124        };
125
126        log::debug!("version id: {}", version_id);
127
128        let options = PutSymlinkOptionsBuilder::new().metadata("x-oss-meta-a", "meta value b").build();
129
130        let response = client.put_symlink(bucket_name, &link_name, &object_key, Some(options));
131        assert!(response.is_ok());
132
133        let ret = response.unwrap();
134        assert!(ret.version_id.is_some());
135
136        let response = client.get_symlink(bucket_name, &link_name, None);
137        assert!(response.is_ok());
138        let ret = response.unwrap();
139        assert_eq!(ret, object_key);
140
141        let response = client.delete_object(bucket_name, &link_name, None);
142        assert!(response.is_ok());
143
144        let response = client.delete_object(bucket_name, &object_key, None);
145        assert!(response.is_ok());
146    }
147}