src/lib.rs
-rw-r--r-- 1.5 KiB
1use std::{fmt::Display, str::FromStr};
2
3use error::Error;
4use oci_spec::image::Digest;
5use regex::Regex;
6use relative_path::RelativePath;
7
8pub mod address;
9pub mod error;
10pub mod oci_interface;
11pub mod storage;
12
13#[cfg(feature = "axum")]
14pub mod axum;
15
16#[cfg(feature = "storage-fs")]
17pub mod storage_fs;
18
19const NAME_REGEXP_MATCH: &str =
20 r"[a-z0-9]+((\.|_|__|-+)[a-z0-9]+)*(\/[a-z0-9]+((\.|_|__|-+)[a-z0-9]+)*)*";
21
22#[derive(Clone, Debug)]
23pub enum TagOrDigest {
24 Tag(String),
25 Digest(Digest)
26}
27
28// TODO: Consider 255 char namespace limit - hostname length per spec docs
29#[derive(Clone)]
30pub struct Namespace(String);
31
32impl Namespace {
33 pub fn path(&self) -> &RelativePath {
34 RelativePath::new(&self.0)
35 }
36}
37
38impl FromStr for Namespace {
39 type Err = Error;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 let regexp = Regex::new(NAME_REGEXP_MATCH).unwrap();
43 if regexp.is_match(s) {
44 Ok(Namespace(s.to_string()))
45 } else {
46 Err(Error::Namespace(s.to_string()))
47 }
48 }
49}
50
51impl Display for Namespace {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 write!(f, "{}", self.0)
54 }
55}
56
57impl AsRef<str> for Namespace {
58 fn as_ref(&self) -> &str {
59 &self.0
60 }
61}
62
63#[cfg(test)]
64mod test {
65 use super::*;
66
67 #[test]
68 fn namespace() {
69 Namespace::from_str("fuu").unwrap();
70 Namespace::from_str("fuu/bar").unwrap();
71 Namespace::from_str("fuu/bar/baz/").unwrap();
72 Namespace::from_str("fuu/bar/baz/qux").unwrap();
73 }
74}