1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use azure::core::errors::AzurePathParseError; use std::borrow::Borrow; pub trait IntoAzurePath { fn container_name(&self) -> Result<&str, AzurePathParseError>; fn blob_name(&self) -> Result<&str, AzurePathParseError>; } impl<T> IntoAzurePath for (T, T) where T: Borrow<str>, { fn container_name(&self) -> Result<&str, AzurePathParseError> { Ok(self.0.borrow()) } fn blob_name(&self) -> Result<&str, AzurePathParseError> { Ok(self.1.borrow()) } } impl<'a> IntoAzurePath for &'a str { fn container_name(&self) -> Result<&str, AzurePathParseError> { match split(self.borrow()) { Ok((container_name, _blob_name)) => Ok(container_name), Err(error) => Err(error), } } fn blob_name(&self) -> Result<&str, AzurePathParseError> { match split(self.borrow()) { Ok((_container_name, blob_name)) => Ok(blob_name), Err(error) => Err(error), } } } fn split(b: &str) -> Result<(&str, &str), AzurePathParseError> { let slash_pos = match b.find('/') { Some(p) => p, None => return Err(AzurePathParseError::PathSeparatorNotFoundError), }; if slash_pos == 0 { return Err(AzurePathParseError::MissingContainerError); } if slash_pos + 1 == b.len() { return Err(AzurePathParseError::MissingBlobError); } if b[slash_pos + 1..].contains('/') { return Err(AzurePathParseError::MultiplePathSeparatorsFoundError); } Ok((&b[0..slash_pos], &b[slash_pos + 1..])) } #[cfg(test)] mod test { use super::*; #[test] fn tuple() { let tuple = ("container", "blob"); assert!(tuple.container_name().unwrap() == "container"); assert!(tuple.blob_name().unwrap() == "blob"); } #[test] fn single_slash() { let path = "container/blob"; let p = &path; assert!(p.container_name().unwrap() == "container"); assert!(path.blob_name().unwrap() == "blob"); } #[test] #[should_panic(expected = "PathSeparatorNotFoundError")] fn no_slash() { let path = "containerblob"; let p = &path; assert!(p.container_name().unwrap() == "container"); assert!(path.blob_name().unwrap() == "blob"); } #[test] #[should_panic(expected = "MultiplePathSeparatorsFoundError")] fn three_slashes() { let path = "container/blob/extra"; let p = &path; assert!(p.container_name().unwrap() == "container"); assert!(path.blob_name().unwrap() == "blob"); } #[test] #[should_panic(expected = "MissingContainerError")] fn missing_container() { let path = "/blob"; let p = &path; assert!(p.container_name().unwrap() == "container"); assert!(path.blob_name().unwrap() == "blob"); } #[test] #[should_panic(expected = "MissingBlobError")] fn missing_blob() { let path = "container/"; let p = &path; assert!(p.container_name().unwrap() == "container"); assert!(path.blob_name().unwrap() == "blob"); } }