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
use serde::{Deserialize, Serialize};

use crate::storage::ResolverMatcher;
use tracing::instrument;

#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
#[serde(default)]
pub struct S3Storage {
  bucket: String,
}

impl S3Storage {
  /// Create a new S3 storage.
  pub fn new(bucket: String) -> Self {
    Self { bucket }
  }

  /// Get the bucket.
  pub fn bucket(&self) -> &str {
    &self.bucket
  }
}

impl<'a> From<ResolverMatcher<'a>> for Option<S3Storage> {
  #[instrument(level = "trace", ret)]
  fn from(resolver_and_query: ResolverMatcher) -> Self {
    let (regex, regex_match) = resolver_and_query.into_inner();
    let bucket = regex.captures(regex_match)?.get(1)?.as_str();

    Some(S3Storage::new(bucket.to_string()))
  }
}

#[cfg(test)]
mod tests {
  use regex::Regex;

  use crate::config::tests::test_config_from_file;
  use crate::storage::Storage;

  use super::*;

  #[test]
  fn config_storage_s3_file() {
    test_config_from_file(
      r#"
        [[resolvers]]
        regex = "regex"

        [resolvers.storage]
        bucket = "bucket"
        "#,
      |config| {
        println!("{:?}", config.resolvers().first().unwrap().storage());
        assert!(matches!(
            config.resolvers().first().unwrap().storage(),
            Storage::S3 { s3_storage } if s3_storage.bucket() == "bucket"
        ));
      },
    );
  }

  #[test]
  fn s3_storage_from_resolver_and_query() {
    let regex = Regex::new("^(bucket)/(?P<key>.*)$").unwrap();

    let result: Option<S3Storage> = ResolverMatcher(&regex, "bucket/id").into();
    let expected = S3Storage::new("bucket".to_string());

    assert_eq!(result.unwrap(), expected);
  }

  #[test]
  fn s3_storage_from_resolver_and_query_no_captures() {
    let regex = Regex::new("^bucket/id$").unwrap();

    let result: Option<S3Storage> = ResolverMatcher(&regex, "/bucket/id").into();

    assert_eq!(result, None);
  }
}