Just trying to see how Rust patterns work in Swift
Last active
April 23, 2022 00:04
-
-
Save igor-makarov/f0c1ce3e9b6fe291b81338bd4cabafc3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// from: https://doc.rust-lang.org/beta/embedded-book/static-guarantees/design-contracts.html#type-states | |
protocol EnabledState {} | |
protocol DirectionState {} | |
protocol ModeState {} | |
struct GpioConfig<IsEnabled: EnabledState, Direction: DirectionState, Mode: ModeState> { | |
var periph: Int64 | |
init(periph: Int64) { | |
self.periph = periph | |
} | |
} | |
struct Disabled: EnabledState {} | |
struct Enabled: EnabledState {} | |
struct Output: DirectionState {} | |
struct Input: DirectionState {} | |
struct PulledLow: ModeState {} | |
struct PulledHigh: ModeState {} | |
struct HighZ: ModeState {} | |
struct DontCare: EnabledState, ModeState, DirectionState {} | |
/// These functions may be used on any GPIO Pin | |
extension GpioConfig { | |
func into_disabled() -> GpioConfig<Disabled, DontCare, DontCare> { | |
// periph modifications omitted | |
.init(periph: periph) | |
} | |
func into_enabled_input() -> GpioConfig<Enabled, Input, HighZ> { | |
// periph modifications omitted | |
.init(periph: periph) | |
} | |
func into_enabled_output() -> GpioConfig<Enabled, Output, DontCare> { | |
// periph modifications omitted | |
.init(periph: periph) | |
} | |
} | |
extension GpioConfig where IsEnabled == Enabled, Direction == Output, Mode == DontCare { | |
mutating func set_bit(_ set_high: Bool) { | |
// periph modifications omitted | |
} | |
} | |
extension GpioConfig where IsEnabled == Enabled, Direction == Input { | |
func bit_is_set() -> Bool { | |
// periph read omitted | |
true | |
} | |
func into_input_high_z() -> GpioConfig<Enabled, Input, HighZ> { | |
// periph modifications omitted | |
.init(periph: periph) | |
} | |
func into_input_pull_down() -> GpioConfig<Enabled, Input, PulledLow> { | |
// periph modifications omitted | |
.init(periph: periph) | |
} | |
func into_input_pull_up() -> GpioConfig<Enabled, Input, PulledHigh> { | |
// periph modifications omitted | |
.init(periph: periph) | |
} | |
} | |
func get_gpio() -> GpioConfig<DontCare, DontCare, DontCare> { | |
// periph code omitted | |
.init(periph: 0) | |
} | |
/* | |
* Example 1: Unconfigured to High-Z input | |
*/ | |
let pin = get_gpio() | |
// Can't do this, pin isn't enabled! | |
// pin.into_input_pull_down(); | |
// Now turn the pin from unconfigured to a high-z input | |
let input_pin = pin.into_enabled_input() | |
// Read from the pin | |
print("pin_state:", input_pin.bit_is_set()) | |
// Can't do this, input pins don't have this interface! | |
// input_pin.set_bit(true) | |
/* | |
* Example 2: High-Z input to Pulled Low input | |
*/ | |
let pulled_low = input_pin.into_input_pull_down() | |
print("pin_state:", pulled_low.bit_is_set()) | |
/* | |
* Example 3: Pulled Low input to Output, set high | |
*/ | |
var output_pin = pulled_low.into_enabled_output() | |
output_pin.set_bit(true) | |
// Can't do this, output pins don't have this interface! | |
// output_pin.into_input_pull_down() | |
print("size:", MemoryLayout.size(ofValue: output_pin)) // 8 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment