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
// Copyright (C) 2017 Christopher R. Field.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use Error;
use LICENSE_FILE_NAME;
use Result;
use RTF_FILE_EXTENSION;
use std::fmt;
use std::path::PathBuf;
use std::str::FromStr;
use Template;
use toml::Value;

#[derive(Clone, Debug, PartialEq)]
pub enum Eula {
    CommandLine(PathBuf),
    Manifest(PathBuf),
    Generate(Template),
    Disabled,
}

impl Eula {
    pub fn new(p: Option<&PathBuf>, manifest: &Value) -> Result<Self> {
        if let Some(ref path) = p {
            Ok(Eula::CommandLine(path.into()))
        } else {
            Eula::from_manifest(&manifest)
        }
    }

    pub fn from_manifest(manifest: &Value) -> Result<Self> {
        if let Some(license_file_path) = manifest.get("package")
            .and_then(|p| p.as_table())
            .and_then(|t| t.get("license-file"))
            .and_then(|l| l.as_str())
            .map(PathBuf::from) {
            trace!("The 'license-file' field is specified in the package's manifest (Cargo.toml)");
            debug!("license_file_path = {:?}", license_file_path);
            if license_file_path.extension().and_then(|s| s.to_str()) == Some(RTF_FILE_EXTENSION) {
                trace!("The '{}' path from the 'license-file' field in the package's \
                       manifest (Cargo.toml) has a RTF file extension.",
                       license_file_path.display());
                if license_file_path.exists() {
                    trace!("The '{}' path from the 'license-file' field of the package's \
                           manifest (Cargo.toml) exists and has a RTF file extension.",
                           license_file_path.exists());
                    Ok(Eula::Manifest(license_file_path.into()))
                } else {
                    Err(Error::Generic(format!(
                        "The '{}' file to be used for the EULA specified in the package's \
                        manifest (Cargo.toml) using the 'license-file' field does not exist.",
                        license_file_path.display()
                    )))
                }
            } else {
                trace!("The '{}' path from the 'license-file' field in the package's \
                       manifest (Cargo.toml) exists but it does not have a RTF file \
                       extension.",
                       license_file_path.display());
                Ok(Eula::Disabled)
            }
        } else {
            if let Some(license_name) = manifest.get("package")
                .and_then(|p| p.as_table())
                .and_then(|t| t.get("license"))
                .and_then(|n| n.as_str()) {
                trace!("The 'license' field is specified in the package's manifest (Cargo.toml)");
                debug!("license_name = {:?}", license_name);
                if let Ok(template) = Template::from_str(license_name) {
                    trace!("An embedded template for the '{}' license from the package's \
                           manifest (Cargo.toml) exists.", license_name);
                    Ok(Eula::Generate(template))
                } else {
                    trace!("The '{}' license from the package's manifest (Cargo.toml) is \
                           unknown or an embedded template does not exist for it", license_name);
                    Ok(Eula::Disabled)
                }
            } else {
                trace!("The 'license' field is not specified in the package's manifest (Cargo.toml)");
                Ok(Eula::Disabled)
            }
        }
    }
}

impl fmt::Display for Eula {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Eula::CommandLine(ref path) => path.display().fmt(f),
            Eula::Manifest(ref path) => path.display().fmt(f),
            Eula::Generate(..) => write!(f, "{}.{}", LICENSE_FILE_NAME, RTF_FILE_EXTENSION),
            Eula::Disabled => write!(f, "Disabled"),
        }
    }
}