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
//! Ocean packages, also known as drops 💧.

#[cfg(feature = "toml")]
mod package;

pub mod kind;
pub mod license;
pub mod manifest;
pub mod name;
pub mod source;
pub mod version;

use self::kind::{App, Exe, Font, Lib};

#[doc(inline)]
pub use self::{
    kind::Kind,
    license::License,
    manifest::Manifest,
    name::Name,
    source::Source,
    version::Version,
};

#[cfg(feature = "toml")]
#[doc(inline)]
pub use self::{
    package::*,
};

/// Defines an Ocean package, also known as a drop 💧.
#[derive(Clone, Debug)]
pub enum Drop {
    /// A package with a graphical interface.
    App(App),
    /// A package that can be executed; e.g. CLI tool or script.
    Exe(Exe),
    /// A package for a typeface with specific properties; e.g. bold, italic.
    Font(Font),
    /// A package for a library of a given language.
    Lib(Lib),
}

impl From<App> for Drop {
    #[inline]
    fn from(drop: App) -> Self {
        Self::App(drop)
    }
}

impl From<Exe> for Drop {
    #[inline]
    fn from(drop: Exe) -> Self {
        Self::Exe(drop)
    }
}

impl From<Font> for Drop {
    #[inline]
    fn from(drop: Font) -> Self {
        Self::Font(drop)
    }
}

impl From<Lib> for Drop {
    #[inline]
    fn from(drop: Lib) -> Self {
        Self::Lib(drop)
    }
}

impl Drop {
    ///
    pub fn query<S>(query: &name::Query<S>) -> Result<Self, ()>
        where S: AsRef<str>
    {
        let query = query.to_ref::<str>();
        unimplemented!("TODO: Find '{}' drop", query);
    }

    /// Returns the kind of drop.
    pub fn kind(&self) -> Kind {
        match self {
            Self::App(_)  => Kind::App,
            Self::Exe(_)  => Kind::Exe,
            Self::Font(_) => Kind::Font,
            Self::Lib(_)  => Kind::Lib,
        }
    }

    /// Returns basic metadata for the drop.
    pub fn metadata(&self) -> &Metadata {
        match self {
            Self::App(app)   => app.metadata(),
            Self::Exe(exe)   => exe.metadata(),
            Self::Font(font) => font.metadata(),
            Self::Lib(lib)   => lib.metadata(),
        }
    }
}

/// Information common to all drops.
#[derive(Clone, Debug)]
pub struct Metadata {
    // TODO: Replace `scope` and `name` with a `ScopedNameRef`

    /// The drop's namespace.
    pub scope: String,
    /// The drop's unique name within its namespace.
    pub name: String,
}