summaryrefslogtreecommitdiffstats
path: root/src/package/dependency/mod.rs
blob: a4f6367389c2108aa28d9a7709d36e1c62b7c685 (plain)
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
114
115
116
//
// Copyright (c) 2020-2021 science+computing ag and other contributors
//
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//

use anyhow::anyhow;
use anyhow::Result;
use lazy_static::lazy_static;
use regex::Regex;

use crate::package::PackageName;
use crate::package::PackageVersionConstraint;

mod build;
pub use build::*;

mod runtime;
pub use runtime::*;

pub trait StringEqual {
    fn str_equal(&self, s: &str) -> bool;
}

pub trait ParseDependency {
    fn parse_as_name_and_version(&self) -> Result<(PackageName, PackageVersionConstraint)>;
}

lazy_static! {
    pub(in crate::package::dependency)  static ref DEPENDENCY_PARSING_RE: Regex =
        Regex::new("^(?P<name>[[:alpha:]]([[[:alnum:]]-_])*) (?P<version>([\\*=><])?[[:alnum:]]([[[:alnum:]][[:punct:]]])*)$").unwrap();
}

/// Helper function for the actual implementation of the ParseDependency trait.
///
/// TODO: Reimplement using pom crate
pub(in crate::package::dependency) fn parse_package_dependency_string_into_name_and_version(
    s: &str,
) -> Result<(PackageName, PackageVersionConstraint)> {
    let caps = crate::package::dependency::DEPENDENCY_PARSING_RE
        .captures(s)
        .ok_or_else(|| {
            anyhow!(
                "Could not parse into package name and package version constraint: '{}'",
                s
            )
        })?;

    let name = caps
        .name("name")
        .ok_or_else(|| anyhow!("Could not parse name: '{}'", s))?;

    let vers = caps
        .name("version")
        .ok_or_else(|| anyhow!("Could not parse version: '{}'", s))?;

    let v = PackageVersionConstraint::parser().parse(vers.as_str().as_bytes())?;

    Ok((PackageName::from(String::from(name.as_str())), v))
}

#[cfg(test)]
mod tests {
    use super::*;

    use crate::package::PackageName;
    use crate::package::PackageVersion;

    //
    // helper functions
    //

    fn name(s: &'static str) -> PackageName {
        PackageName::from(String::from(s))
    }

    fn exact(s: &'static str) -> PackageVersion {
        PackageVersion::from(String::from(s))
    }

    //
    // tests
    //

    #[test]
    fn test_dependency_conversion_1() {
        let s = "vim =8.2";
        let d = Dependency::from(String::from(s));

        let (n, c) = d.parse_as_name_and_version().unwrap();

        assert_eq!(n, name("vim"));
        assert_eq!(
            c,
            PackageVersionConstraint::from_version(String::from("="), exact("8.2"))
        );
    }

    #[test]
    fn test_dependency_conversion_2() {
        let s = "gtk15 =1b";
        let d = Dependency::from(String::from(s));

        let (n, c) = d.parse_as_name_and_version().unwrap();

        assert_eq!(n, name("gtk15"));
        assert_eq!(
            c,
            PackageVersionConstraint::from_version(String::from("="), exact("1b"))
        );
    }
}