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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright 2023-2023 CrabNebula Ltd.
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

//! # cargo-packager-utils
//!
//! Contain reusable components of the cargo-packager ecosystem.

use std::fmt::Display;

pub mod current_exe;

// NOTE: When making changes to this enum,
// make sure to also update in updater and resource-resolver bindings if needed
/// Types of supported packages by [`cargo-packager`](https://docs.rs/cargo-packager).
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[cfg_attr(feature = "clap", value(rename_all = "lowercase"))]
#[non_exhaustive]
pub enum PackageFormat {
    /// All available package formats for the current platform.
    ///
    /// See [`PackageFormat::platform_all`]
    #[cfg(feature = "cli")]
    All,
    /// The default list of package formats for the current platform.
    ///
    /// See [`PackageFormat::platform_default`]
    #[cfg(feature = "cli")]
    Default,
    /// The macOS application bundle (.app).
    App,
    /// The macOS DMG package (.dmg).
    Dmg,
    /// The Microsoft Software Installer (.msi) through WiX Toolset.
    Wix,
    /// The NSIS installer (.exe).
    Nsis,
    /// The Linux Debian package (.deb).
    Deb,
    /// The Linux AppImage package (.AppImage).
    AppImage,
    /// The Linux Pacman package (.tar.gz and PKGBUILD)
    Pacman,
}

impl Display for PackageFormat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.short_name())
    }
}

impl PackageFormat {
    /// Maps a short name to a [PackageFormat].
    /// Possible values are "deb", "pacman", "appimage", "dmg", "app", "wix", "nsis".
    pub fn from_short_name(name: &str) -> Option<PackageFormat> {
        // Other types we may eventually want to support: apk.
        match name {
            "app" => Some(PackageFormat::App),
            "dmg" => Some(PackageFormat::Dmg),
            "wix" => Some(PackageFormat::Wix),
            "nsis" => Some(PackageFormat::Nsis),
            "deb" => Some(PackageFormat::Deb),
            "appimage" => Some(PackageFormat::AppImage),
            _ => None,
        }
    }

    /// Gets the short name of this [PackageFormat].
    pub fn short_name(&self) -> &'static str {
        match *self {
            #[cfg(feature = "cli")]
            PackageFormat::All => "all",
            #[cfg(feature = "cli")]
            PackageFormat::Default => "default",
            PackageFormat::App => "app",
            PackageFormat::Dmg => "dmg",
            PackageFormat::Wix => "wix",
            PackageFormat::Nsis => "nsis",
            PackageFormat::Deb => "deb",
            PackageFormat::AppImage => "appimage",
            PackageFormat::Pacman => "pacman",
        }
    }

    /// Gets the list of the possible package types on the current OS.
    ///
    /// - **macOS**: App, Dmg
    /// - **Windows**: Nsis, Wix
    /// - **Linux**: Deb, AppImage, Pacman
    pub fn platform_all() -> &'static [PackageFormat] {
        &[
            #[cfg(target_os = "macos")]
            PackageFormat::App,
            #[cfg(target_os = "macos")]
            PackageFormat::Dmg,
            #[cfg(target_os = "windows")]
            PackageFormat::Wix,
            #[cfg(target_os = "windows")]
            PackageFormat::Nsis,
            #[cfg(any(
                target_os = "linux",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "netbsd",
                target_os = "openbsd"
            ))]
            PackageFormat::Deb,
            #[cfg(any(
                target_os = "linux",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "netbsd",
                target_os = "openbsd"
            ))]
            PackageFormat::AppImage,
            #[cfg(any(
                target_os = "linux",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "netbsd",
                target_os = "openbsd"
            ))]
            PackageFormat::Pacman,
        ]
    }

    /// Returns the default list of targets this platform
    ///
    /// - **macOS**: App, Dmg
    /// - **Windows**: Nsis
    /// - **Linux**: Deb, AppImage, Pacman
    pub fn platform_default() -> &'static [PackageFormat] {
        &[
            #[cfg(target_os = "macos")]
            PackageFormat::App,
            #[cfg(target_os = "macos")]
            PackageFormat::Dmg,
            #[cfg(target_os = "windows")]
            PackageFormat::Nsis,
            #[cfg(any(
                target_os = "linux",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "netbsd",
                target_os = "openbsd"
            ))]
            PackageFormat::Deb,
            #[cfg(any(
                target_os = "linux",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "netbsd",
                target_os = "openbsd"
            ))]
            PackageFormat::AppImage,
            #[cfg(any(
                target_os = "linux",
                target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "netbsd",
                target_os = "openbsd"
            ))]
            PackageFormat::Pacman,
        ]
    }

    /// Gets a number representing priority which used to sort package types
    /// in an order that guarantees that if a certain package type
    /// depends on another (like Dmg depending on MacOsBundle), the dependency
    /// will be built first
    ///
    /// The lower the number, the higher the priority
    pub fn priority(&self) -> u32 {
        match self {
            #[cfg(feature = "cli")]
            PackageFormat::All => 0,
            #[cfg(feature = "cli")]
            PackageFormat::Default => 0,
            PackageFormat::App => 0,
            PackageFormat::Wix => 0,
            PackageFormat::Nsis => 0,
            PackageFormat::Deb => 0,
            PackageFormat::AppImage => 0,
            PackageFormat::Pacman => 0,
            PackageFormat::Dmg => 1,
        }
    }
}