platform_lp/
platform.rs

1use std::slice::Iter;
2
3use PartialPlatform;
4use Architecture;
5
6// the str constant values
7const WIN64 : &str = "Windows x86_64";
8const WIN32 : &str = "Windows x32";
9const NIX64 : &str = "Linux x86_64";
10const NIX32 : &str = "Linux x32";
11const MAC64 : &str = "Mac OS x86_64";
12const MAC32 : &str = "Mac OS x32";
13const NONE : &str = "None";
14
15// the short str constant values
16const S_WIN64 : &str = "win64";
17const S_WIN32 : &str = "win32";
18const S_NIX64 : &str = "nix64";
19const S_NIX32 : &str = "nix32";
20const S_MAC64 : &str = "mac64";
21const S_MAC32 : &str = "mac32";
22
23/// Platform struct, designed to completely describe the current platform
24/// or other possible platforms.
25#[derive(Debug,PartialEq,Hash,Eq)]
26pub enum Platform {
27    Win64,
28    Win32,
29    Nix64,
30    Nix32,
31    Mac64,
32    Mac32,
33    None
34}
35
36impl Platform {
37
38    // MEMBER FUNCTIONS /////////////////////////////////
39
40    // creation functions ///////////////////////////////
41
42    pub fn new(platform : &str) -> Platform {
43        //! Creates a new platform from a string.
44        //!
45        //! Works through a number of different possibilities to make sure 
46        //! the correct platform is matched based on the string entered.
47        //! 
48        //! Supports exact matches to the enums [as_str](#method.as_str) and [as_short_str](#method.as_short_str)
49        //! as well as pattern matching with keywords such as:
50        //! - 64,32
51        //! - win,nix,linux,mac
52        //! - lxx,wxx,mxx (for short codes)
53
54        let mut plat = Platform::None;
55
56        match platform {
57            NIX64 => { plat = Platform::Nix64; },
58            NIX32 => { plat = Platform::Nix32; },
59            WIN64 => { plat = Platform::Win64; },
60            WIN32 => { plat = Platform::Win32; },
61            MAC64 => { plat = Platform::Mac64; },
62            MAC32 => { plat = Platform::Mac32; },
63            _ => { }
64        }
65
66        match platform.to_lowercase().as_str() {
67            "linux64" | "lin64" | "nix64" | "l64" => { plat = Platform::Nix64; },
68            "linux32" | "lin32" | "nix32" | "l32" => { plat = Platform::Nix32; },
69            "windows64" | "win64" | "w64" => { plat = Platform::Win64; },
70            "windows32" | "win32" | "w32" => { plat = Platform::Win32; },
71            "macos64" | "mac64" | "m64" => { plat = Platform::Mac64; },
72            "macos32" | "mac32" | "m32" => { plat = Platform::Mac32; }
73            _ => { }
74        }
75
76        let string_lower = platform.to_lowercase();
77
78        // architecture
79        let mut arch : u8 = 32;
80        if string_lower.contains("64") { 
81            arch = 64; 
82        }
83        // platform
84        if string_lower.contains("win") { 
85            plat = if arch == 32 { Platform::Win32 } 
86                   else { Platform::Win64 }; 
87        }
88        if string_lower.contains("nix") || string_lower.contains("lin") { 
89            plat = if arch == 32 { Platform::Nix32 } 
90                   else { Platform::Nix64 }; 
91        }
92        if string_lower.contains("mac") || string_lower.contains("apple") { 
93            plat = if arch == 32 { Platform::Mac32 } 
94                   else { Platform::Mac64 }; 
95        }
96
97        plat
98    }
99
100    pub fn clone(&self) -> Platform {
101        //! Creates a copy of the enum object.
102
103        match *self {
104            Platform::Win64 => { Platform::Win64 },
105            Platform::Win32 => { Platform::Win32 },
106            Platform::Nix64 => { Platform::Nix64 },
107            Platform::Nix32 => { Platform::Nix32 },
108            Platform::Mac64 => { Platform::Mac64 },
109            Platform::Mac32 => { Platform::Mac32 },
110            Platform::None => { Platform::None }
111        }
112    }
113
114    // display / io functions ///////////////////////////
115
116    pub fn display(&self) -> &'static str { 
117        //! Displays the platform object using [as_str](#method.as_str)
118
119        self.as_str() 
120    }
121
122    pub fn to_string(&self) -> String { 
123        //! returns a String object with the &str value of the platform
124
125        self.as_str().to_string() 
126    }
127
128    pub fn as_str(&self) -> &'static str {
129        //! Returns a &str constant value for each type.
130        //! - Win64 === 'Windows x86_64'
131        //! - Win32 === 'Windows x32'
132        //! - Nix64 === 'Linux x86_64'
133        //! - Nix32 === 'Linux x32'
134        //! - Mac64 === 'Mac OS x86_64'
135        //! - Mac32 === 'Mac OS x32'
136        //! - None === 'None'
137
138        match *self {
139            Platform::Win64 => { WIN64 },
140            Platform::Win32 => { WIN32 },
141            Platform::Nix64 => { NIX64 },
142            Platform::Nix32 => { NIX32 },
143            Platform::Mac64 => { MAC64 },
144            Platform::Mac32 => { MAC32 },
145            Platform::None => { NONE }
146        }
147    }
148
149    pub fn to_short_string(&self) -> String { 
150        //! returns a String object with the short &str value of the platform
151
152        self.as_short_str().to_string() 
153    }
154
155    pub fn as_short_str(&self) -> &'static str {
156        //! Returns a short &str constant value
157        //! 
158        //! - Win64 === 'win64'
159        //! - Win32 === 'win32'
160        //! - Nix64 === 'nix64'
161        //! - Nix32 === 'nix32'
162        //! - Mac64 === 'mac64'
163        //! - Mac32 === 'mac32'
164        //! - None === 'None'
165
166        match *self {
167            Platform::Win64 => { S_WIN64 },
168            Platform::Win32 => { S_WIN32 },
169            Platform::Nix64 => { S_NIX64 },
170            Platform::Nix32 => { S_NIX32 },
171            Platform::Mac64 => { S_MAC64 },
172            Platform::Mac32 => { S_MAC32 },
173            Platform::None => { NONE }
174        }
175    }
176
177    // working functions //////////////////////////////////
178
179    pub fn is_valid_execution_platform(&self) -> bool {
180        //! Checks if a a binary were built for the `self` platform
181        //! could be executed on the current user platform.
182        //! 
183        //! Assumes that 32 bit applications can be executed on 64 bit
184        //! platforms. If you don't want to assume this then don't use this
185        //! funtion and instead check absolute equality (==).
186
187        let valid_platforms = Platform::get_valid_execution_platform();
188
189        for platform in valid_platforms {
190            if &platform == self {
191                return true;
192            }
193        }
194
195        false
196    }
197
198    pub fn is_compatible(&self,other : &Platform) -> bool {
199        //! Checks if this platform is compatible with the other platform,
200        //! 
201        //! Works on the assumption that 32 bit is compatible with 64 bit.
202        
203        let exec_plats = Platform::get_execution_platform_for(other);
204
205        for plat in exec_plats {
206            if plat == *self { 
207                return true;
208            }
209        }
210
211        false
212    }
213
214    // STATIC FUNCTIONS /////////////////////////////////////
215
216    pub fn get_user_platform() -> Platform {
217        //! Returns the current user platform
218
219        #[cfg(all(unix,target_pointer_width = "64"))]
220            return Platform::Nix64;
221        #[cfg(all(unix,target_pointer_width = "32"))]
222            return Platform::Nix32;
223        #[cfg(all(windows,target_pointer_width = "64"))]
224            return Platform::Win64;
225        #[cfg(all(windows,target_pointer_width = "32"))]
226            return Platform::Win32;
227        #[cfg(all(macos,target_pointer_width = "64"))]
228            return Platform::Mac64;
229        #[cfg(all(macos,target_pointer_width = "32"))]
230            return Platform::Mac32;
231    }
232
233    fn get_execution_platform_for(platform : &Platform) -> Vec<Platform> {
234
235        match *platform {
236            Platform::Win64 => vec![Platform::Win64,Platform::Win32],
237            Platform::Win32 => vec![Platform::Win32],
238            Platform::Nix64 => vec![Platform::Nix64,Platform::Nix32],
239            Platform::Nix32 => vec![Platform::Nix32],
240            Platform::Mac64 => vec![Platform::Mac64,Platform::Mac32],
241            Platform::Mac32 => vec![Platform::Mac32],
242            Platform::None => Vec::new()
243        }
244    }
245
246    pub fn get_valid_execution_platform() -> Vec<Platform> {
247        //! Returns a Vec of all the available execution platforms
248        //!
249        //! Typically its a vector of 1, but also returns the 32bit version on 64bit systems.
250        
251        Platform::get_execution_platform_for(&Platform::get_user_platform())
252    }
253
254    pub fn iterator() -> Iter<'static, Platform> {
255        //! An iterator that iterates through all the defined platforms
256
257        static PLATFORMS: [Platform; 6] = [
258            Platform::Win64,
259            Platform::Win32,
260            Platform::Nix64,
261            Platform::Nix32,
262            Platform::Mac64,
263            Platform::Mac32
264        ];
265        PLATFORMS.into_iter()
266    }
267}
268
269impl std::fmt::Display for Platform {
270    fn fmt(&self, f : &mut std::fmt::Formatter) -> std::fmt::Result {
271        write!(f,"{}",self.to_string())
272    }
273}
274
275impl PartialEq<PartialPlatform> for Platform {
276    fn eq(&self, other: &PartialPlatform) -> bool {
277        other == self
278    }
279}
280
281impl PartialEq<Architecture> for Platform {
282    fn eq(&self, other: &Architecture) -> bool {
283        other == self
284    }
285}