forked from NeedleInAJayStack/Units
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConvert.swift
More file actions
62 lines (53 loc) · 2.03 KB
/
Convert.swift
File metadata and controls
62 lines (53 loc) · 2.03 KB
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
import ArgumentParser
import Units
struct Convert: ParsableCommand {
static let configuration = CommandConfiguration(
abstract: "Convert a measurement expression to a specified unit.",
discussion: """
Run `unit list` to see the supported unit symbols and names. Unless arguments are wrapped \
in quotes, the `*` character may need to be escaped.
The arguments use the unit and measurement serialization format. For more details, see \
https://github.com/NeedleInAJayStack/Units/blob/main/README.md#serialization
EXAMPLES:
unit convert 1ft m
unit convert 1_ft meter
unit convert 5.4_kW\\*hr J
unit convert 5.4e-3_km/s mi/hr
unit convert "12 kg*m/s^2" "N"
unit convert "8kg * 3m / 2s^2" "N"
"""
)
@Argument(help: """
The expression to compute to convert. This must follow the expression parsing rules found \
in https://github.com/NeedleInAJayStack/Units/blob/main/README.md#serialization. \
For convenience, you may use an underscore `_` to represent spaces.
""")
var from: Expression
@Argument(help: """
The unit to convert to. This can either be a unit name, a unit symbol, or an equation of \
unit symbols.
Example: unit convert 1_ft meter -> 0.3048 m
""")
var to: Units.Unit
func run() throws {
try print(from.solve().convert(to: to))
}
}
let registry = Units.Registry.default
extension Units.Expression: ArgumentParser.ExpressibleByArgument {
public convenience init?(argument: String) {
let argument = argument.replacingOccurrences(of: "_", with: " ")
try? self.init(argument)
}
}
extension Units.Unit: ArgumentParser.ExpressibleByArgument {
public init?(argument: String) {
if let unit = try? Self(fromName: argument, registry: registry) {
self = unit
} else if let unit = try? Self(fromSymbol: argument, registry: registry) {
self = unit
} else {
return nil
}
}
}