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
//  LOCATIONS.rs
//    by Lut99
//
//  Created:
//    07 Sep 2022, 10:48:30
//  Last edited:
//    14 Nov 2022, 10:04:13
//  Auto updated?
//    Yes
//
//  Description:
//!   Defines a few enums that help analysing location restrictions on a
//!   node.
//

use brane_dsl::location::AllowedLocations;
use serde::{Deserialize, Serialize};


/***** LIBRARY *****/
/// Defines a single location to run.
pub type Location = String;



/// Contains location restrictions for a certain node.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Locations {
    /// All locations are allowed.
    All,
    /// If not all, then the following locations are allowed as a whitelist.
    Restricted(Vec<Location>),
}

impl Locations {
    /// Returns the restrictive list of locations if this Locations is, in fact, restrictive.
    ///
    /// # Returns
    /// A slice that to the whitelist of locations.
    ///
    /// # Panics
    /// This function panics if the Locations was not `Locations::Restricted`. Use `Locations::is_restrictive` to query beforehand.
    #[inline]
    pub fn restricted(&self) -> &[Location] {
        if let Self::Restricted(locs) = self {
            locs
        } else {
            panic!("Cannot unwrap Locations::{self:?} as restricted");
        }
    }

    /// Returns whether this Locations is an open-to-all kinda thing.
    #[inline]
    pub fn is_all(&self) -> bool { matches!(self, Self::All) }

    /// Returns whether this Locations is a restrictive list.
    #[inline]
    pub fn is_restrictive(&self) -> bool { matches!(self, Self::Restricted(_)) }
}

impl From<AllowedLocations> for Locations {
    #[inline]
    fn from(value: AllowedLocations) -> Self {
        match value {
            AllowedLocations::All => Self::All,
            AllowedLocations::Exclusive(locs) => Self::Restricted(locs.into_iter().map(|l| l.into()).collect()),
        }
    }
}