install_framework_core/
builder.rs

1// Copyright 2021 Yuri6037
2
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
21use std::collections::HashMap;
22
23use crate::interface::Installer;
24use crate::interface::PostInstall;
25use crate::interface::PostUninstall;
26use crate::interface::Interface;
27use crate::interface::InstallMethod;
28use crate::common::get_install_dir;
29
30pub struct InstallerBuilder<'a>
31{
32    name: &'static str,
33    version: &'static str,
34    author: &'static str,
35    install: &'a mut dyn Installer,
36    user_install: bool,
37    sys_install: bool,
38    post_install: Option<&'a mut dyn PostInstall>,
39    post_uninstall: Option<&'a mut dyn PostUninstall>,
40    resources: HashMap<&'static str, &'static [u8]>
41}
42
43impl <'a> InstallerBuilder<'a>
44{
45    pub fn new(install: &'a mut dyn Installer) -> InstallerBuilder
46    {
47        return InstallerBuilder
48        {
49            name: "Generic",
50            version: "1.0",
51            author: "Unknown",
52            install: install,
53            user_install: false,
54            sys_install: false, //By default let the installer decide if it prefers system wide install or user install
55            post_install: None,
56            post_uninstall: None,
57            resources: HashMap::new()
58        };
59    }
60
61    /// Sets the global installer name
62    /// 
63    /// # Arguments
64    /// 
65    /// * `version` - The version of this installer as a static string
66    pub fn set_name(mut self, name: &'static str) -> Self
67    {
68        self.name = name;
69        return self;
70    }
71
72    /// Sets the global installer version
73    /// 
74    /// # Arguments
75    /// 
76    /// * `version` - The version of this installer as a static string
77    pub fn set_version(mut self, version: &'static str) -> Self
78    {
79        self.version = version;
80        return self;
81    }
82
83    /// Sets the global installer author
84    /// 
85    /// # Arguments
86    /// 
87    /// * `author` - The author of this installer as a static string
88    pub fn set_author(mut self, author: &'static str) -> Self
89    {
90        self.author = author;
91        return self;
92    }
93
94    /// Add a resource
95    /// 
96    /// # Arguments
97    /// 
98    /// * `path` - path to use for referencing in the install script
99    /// * `bytes` - resource binary data (use include_bytes!)
100    pub fn add_resource(mut self, path: &'static str, bytes: &'static [u8]) -> Self
101    {
102        self.resources.insert(path, bytes);
103        return self;
104    }
105
106    /// Add a PostInstall step to this installer
107    /// 
108    /// # Arguments
109    /// 
110    /// * `obj` - reference to the PostInstall trait
111    pub fn add_post_install_step(mut self, obj: &'a mut dyn PostInstall) -> Self
112    {
113        self.post_install = Some(obj);
114        return self;
115    }
116
117    /// Add a PostUninstall step to this installer
118    /// 
119    /// # Arguments
120    /// 
121    /// * `obj` - reference to the PostUninstall trait
122    pub fn add_post_uninstall_step(mut self, obj: &'a mut dyn PostUninstall) -> Self
123    {
124        self.post_uninstall = Some(obj);
125        return self;
126    }
127
128    /// Allows user installs
129    pub fn allow_user_install(mut self) -> Self
130    {
131        self.user_install = true;
132        return self;
133    }
134
135    /// Allows system wide installs
136    pub fn allow_system_install(mut self) -> Self
137    {
138        self.sys_install = true;
139        return self;
140    }
141
142    fn run_internal<TInterface: Interface>(&mut self, interface: &mut TInterface) -> Result<(), TInterface::ErrorType>
143    {
144        interface.welcome(self.name, self.version, self.author)?;
145        let mut method = InstallMethod::SystemInstall;
146        if self.user_install && !self.sys_install
147        {
148            method = InstallMethod::UserInstall;
149        }
150        else if self.user_install && self.sys_install
151        {
152            method = interface.get_install_method()?;
153        }
154        let uninstall = interface.should_uninstall()?;
155        let dir = get_install_dir(&method);
156        if uninstall
157        {
158            interface.run_uninstall(self.install, &dir, method, &self.resources)?;
159            if let Some(obj) = &mut self.post_uninstall
160            {
161                interface.run_post_uninstall(*obj, &dir)?;
162            }
163        }
164        else
165        {
166            interface.run_install(self.install, &dir, method, &self.resources)?;
167            if let Some(obj) = &mut self.post_install
168            {
169                interface.run_post_install(*obj, &dir)?;
170            }
171        }
172        return Ok(());
173    }
174
175    pub fn run<TInterface: Interface>(&mut self, interface: &mut TInterface) -> i32
176    {
177        match self.run_internal(interface)
178        {
179            Ok(()) => interface.finish(),
180            Err(e) => interface.error(e)
181        }
182    }
183}