### 3 unstable releases

Uses old Rust 2015

0.1.0 | May 29, 2015 |
---|---|

0.0.2 | May 28, 2015 |

0.0.1 | May 26, 2015 |

#**893** in Rust patterns

**MIT**license

19KB

317 lines

# units

**Units of Measure** for Rust. Easy to use, type-safe and customizable.

## Usage (Example)

`#``[``macro_use``]` `extern` `crate` units`;`
`//` It is recommended to put units inside a separate module
`pub` `mod` `my_units` `{`
`//` Here we define our unit system with three units
`units!` `{`
MyUnits `{`
Meter`[`m`]``,`
Second`[`s`]``,`
Mile`[`mile`]`
`}`
`}`
`}`
`//` Import the unit constants and also the dimensionless unit `one`
`use` `my_units``::``f64``::``{`one`,` m`,` s`,` mile`}``;`
`fn` `main``(``)`` ``{`
`let` km `=` `1000.``*`m`;` `//` Define the `km` unit as 1000 meter
`let` h `=` `60.``*``60.``*`s`;` `//` Define an hour as 60 * 60 seconds
`//` These units could also have been defined as separate base units,
`//` in order to further reduce the risk to mix them up.
`//` Let's calculate how far a car has moved if it has accelerated
`//` uniformly from 0 to 100 km/h in 12 seconds
`let` initial_speed `=` `0.``*`km`/`h`;`
`let` final_speed `=` `100.``*`km`/`h`;`
`let` time `=` `12.``*`s`;`
`let` acceleration `=` `(`final_speed `-` initial_speed`)``/`time`;`
`let` result `=` `0.``5` `*` acceleration `*` time `*` time`;` `//` s = a/2 * t^2
`//` Here we use debug formatting, which will automatically print the base dimensions
`println!``(``"``{:?}``"``,` result`)``;` `//` This will print `166.66666666666669 m`
`//` Let's convert the result to miles
`let` meter_per_mile `=` `1609.``344``*`m`/`mile`;` `//` This has unit `m/mile`
`let` result_in_miles `=` result `/` meter_per_mile`;` `//` This has unit `mile`
`//` Here we get a dimensionless value by eliminating the unit, then use deref (*) to extract the raw f64.
`println!``(``"``{}` miles`"``,` `*``(`result_in_miles`/`mile`)``)``;` `//` This will print `0.103561865372889 miles`
`//` Now we want to know how long a ball will fall until it reaches the
`//` floor if dropped from a height of 10 meters
`let` height `=` `1.``5``*`m`;`
`let` g `=` `9.``81``*`m`/`s`/`s`;` `//` Use a gravitational constant of 9.81 m/s^2
`let` time `=` `(``2.` `*` height `/` g`)``.``sqrt``(``)``;` `//` sqrt() takes care of the units
`//` Print the result in milliseconds and round to 2 digits
`let` ms `=` `0.``001``*`s`;` `//` 1 ms = 0.001 s
`println!``(``"`The ball falls for `{:.2}` ms until it hits the ground.`"``,` `*``(`time`/`ms`)``)``;`
`//` The above will print `The ball falls for 553.00 ms until it hits the ground.`
`}`

Use

to run this example.`cargo`` run --example basics`

^{There is an alternative, safer syntax for assigning units to values using function call operator overloading, but this is currently only available in Rust nightly. See examples/basics.rs for both versions.}

## How does it work?

The macro invocation shown above will generate a struct

, where the first type parameter is a special marker to get the dimension right (it contains exponents for every base unit, encoded as type-level integers). `MyUnits <U,T=f64>`

`Meter`

, `Second`

and `Mile`

will be type aliases for this marker type with the correct exponents.The second type parameter denotes the wrapped numeric type (defaults to

). The autogenerated child modules `f64`

and `my_units ::`f64

`my_units``::`f32

then both contain the constants `m`

, `s`

and `mile`

, each of the correct dimension and wrapping the value `1.``0`

. For example, `f64``::`m

is of type `MyUnits``<`Meter, `f64``>`

.Additionally, the type

and the constant `One`

are provided for dimensionless values, and only those can be unwrapped using the `one`

trait (this works automatically for method calls, but sometimes needs to be made explicit using the `Deref`

prefix operator, see the example above).`*`

#### Dependencies

~28KB