diff mbox series

[libgpiod,4/4] bindings: rust: examples: add dedicated examples

Message ID 20230614035426.15097-5-warthog618@gmail.com
State New
Headers show
Series dedicated examples | expand

Commit Message

Kent Gibson June 14, 2023, 3:54 a.m. UTC
Add rust equivalents of the core examples.

Signed-off-by: Kent Gibson <warthog618@gmail.com>
---
 .../rust/libgpiod/examples/get_line_value.rs  | 28 +++++++++++
 .../libgpiod/examples/toggle_line_value.rs    | 43 ++++++++++++++++
 .../libgpiod/examples/watch_line_value.rs     | 50 +++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 bindings/rust/libgpiod/examples/get_line_value.rs
 create mode 100644 bindings/rust/libgpiod/examples/toggle_line_value.rs
 create mode 100644 bindings/rust/libgpiod/examples/watch_line_value.rs

Comments

Erik Schilling June 14, 2023, 7:52 a.m. UTC | #1
On Wed Jun 14, 2023 at 5:54 AM CEST, Kent Gibson wrote:
> Add rust equivalents of the core examples.
>
> Signed-off-by: Kent Gibson <warthog618@gmail.com>

Reviewed-by: Erik Schilling <erik.schilling@linaro.org>

Some nit-picks below, but those are a matter of taste and the change
looks ok either way.

> ---
>  .../rust/libgpiod/examples/get_line_value.rs  | 28 +++++++++++
>  .../libgpiod/examples/toggle_line_value.rs    | 43 ++++++++++++++++
>  .../libgpiod/examples/watch_line_value.rs     | 50 +++++++++++++++++++
>  3 files changed, 121 insertions(+)
>  create mode 100644 bindings/rust/libgpiod/examples/get_line_value.rs
>  create mode 100644 bindings/rust/libgpiod/examples/toggle_line_value.rs
>  create mode 100644 bindings/rust/libgpiod/examples/watch_line_value.rs
>
> diff --git a/bindings/rust/libgpiod/examples/get_line_value.rs b/bindings/rust/libgpiod/examples/get_line_value.rs
> new file mode 100644
> index 0000000..732fb71
> --- /dev/null
> +++ b/bindings/rust/libgpiod/examples/get_line_value.rs
> @@ -0,0 +1,28 @@
> +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
> +// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
> +//
> +// Minimal example of reading a single line.
> +
> +use libgpiod::line;

I think one could also just import the other used modules. Or, since
this is an example anyway, just `use libgpiod::*`.

> +
> +fn main() -> libgpiod::Result<()> {
> +    // example configuration - customize to suit your situation
> +    let chip_path = "/dev/gpiochip0";
> +    let line_offset = 5;
> +
> +    let mut lsettings = line::Settings::new()?;

I think `line_settings` would still be an okish length (same below) :).

> +    lsettings.set_direction(line::Direction::Input)?;
> +
> +    let mut lconfig = line::Config::new()?;
> +    lconfig.add_line_settings(&[line_offset], lsettings)?;
> +
> +    let mut rconfig = libgpiod::request::Config::new()?;
> +    rconfig.set_consumer("get-line-value")?;
> +
> +    let chip = libgpiod::chip::Chip::open(&chip_path)?;
> +    let request = chip.request_lines(Some(&rconfig), &lconfig)?;
> +
> +    let value = request.value(line_offset)?;
> +    println!("{:?}", value);

Could also be:
+    println!("{value:?}");
(same below)

> +    Ok(())
> +}
> diff --git a/bindings/rust/libgpiod/examples/toggle_line_value.rs b/bindings/rust/libgpiod/examples/toggle_line_value.rs
> new file mode 100644
> index 0000000..cd7038e
> --- /dev/null
> +++ b/bindings/rust/libgpiod/examples/toggle_line_value.rs
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
> +// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
> +//
> +// Minimal example of toggling a single line.
> +
> +use libgpiod::line;
> +use std::time::Duration;
> +
> +fn toggle_value(value: line::Value) -> line::Value {
> +    match value {
> +        line::Value::Active => line::Value::InActive,
> +        line::Value::InActive => line::Value::Active,
> +    }
> +}
> +
> +fn main() -> libgpiod::Result<()> {
> +    // example configuration - customize to suit your situation
> +    let chip_path = "/dev/gpiochip0";
> +    let line_offset = 5;
> +
> +    let mut value = line::Value::Active;
> +
> +    let mut settings = line::Settings::new()?;
> +    settings
> +        .set_direction(line::Direction::Output)?
> +        .set_output_value(value)?;
> +
> +    let mut lconfig = line::Config::new()?;
> +    lconfig.add_line_settings(&[line_offset], settings)?;
> +
> +    let mut rconfig = libgpiod::request::Config::new()?;
> +    rconfig.set_consumer("toggle-line-value")?;
> +
> +    let chip = libgpiod::chip::Chip::open(&chip_path)?;
> +    let mut req = chip.request_lines(Some(&rconfig), &lconfig)?;
> +
> +    loop {
> +        println!("{:?}", value);
> +        std::thread::sleep(Duration::from_secs(1));
> +        value = toggle_value(value);
> +        req.set_value(line_offset, value)?;
> +    }
> +}
> diff --git a/bindings/rust/libgpiod/examples/watch_line_value.rs b/bindings/rust/libgpiod/examples/watch_line_value.rs
> new file mode 100644
> index 0000000..5a95b6a
> --- /dev/null
> +++ b/bindings/rust/libgpiod/examples/watch_line_value.rs
> @@ -0,0 +1,50 @@
> +// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
> +// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
> +//
> +// Minimal example of watching for edges on a single line.
> +
> +use libgpiod::line;
> +use std::time::Duration;
> +
> +fn main() -> libgpiod::Result<()> {
> +    // example configuration - customize to suit your situation
> +    let chip_path = "/dev/gpiochip0";
> +    let line_offset = 5;
> +
> +    let mut lsettings = line::Settings::new()?;
> +    // assume a button connecting the pin to ground,
> +    // so pull it up and provide some debounce.
> +    lsettings
> +        .set_edge_detection(Some(line::Edge::Both))?
> +        .set_bias(Some(line::Bias::PullUp))?
> +        .set_debounce_period(Duration::from_millis(10));
> +
> +    let mut lconfig = line::Config::new()?;
> +    lconfig.add_line_settings(&[line_offset], lsettings)?;
> +
> +    let mut rconfig = libgpiod::request::Config::new()?;
> +    rconfig.set_consumer("watch-line-value")?;
> +
> +    let chip = libgpiod::chip::Chip::open(&chip_path)?;
> +    let request = chip.request_lines(Some(&rconfig), &lconfig)?;
> +
> +    // a larger buffer is an optimisation for reading bursts of events from the
> +    // kernel, but that is not necessary in this case, so 1 is fine.
> +    let mut buffer = libgpiod::request::Buffer::new(1)?;
> +    loop {
> +        // blocks until at least one event is available
> +        let events = request.read_edge_events(&mut buffer)?;
> +        for event in events {
> +            let event = event?;
> +            println!(
> +                "line: {}, type: {}, event #{}",
> +                event.line_offset(),
> +                match event.event_type()? {
> +                    line::EdgeKind::Rising => "Rising ",
> +                    line::EdgeKind::Falling => "Falling",
> +                },
> +                event.line_seqno()
> +            );

println!("{: <8}") could also be used to pad things (would allow
removing the trailing space).

> +        }
> +    }
> +}
> -- 
> 2.40.1

- Erik
Kent Gibson June 14, 2023, 8:18 a.m. UTC | #2
On Wed, Jun 14, 2023 at 09:52:20AM +0200, Erik Schilling wrote:
> On Wed Jun 14, 2023 at 5:54 AM CEST, Kent Gibson wrote:
> > Add rust equivalents of the core examples.
> >
> > Signed-off-by: Kent Gibson <warthog618@gmail.com>
> 
> Reviewed-by: Erik Schilling <erik.schilling@linaro.org>
> 
> Some nit-picks below, but those are a matter of taste and the change
> looks ok either way.
> 
> > +
> > +use libgpiod::line;
> 
> I think one could also just import the other used modules. Or, since
> this is an example anyway, just `use libgpiod::*`.
> 

I'm never keen on using `::*`, as subsequent changes could pull in symbols
that conflict with locals.

And as this is an example I wanted to be explicit as to where the symbols
originate, especially as there is some overlap, e.g. line::Config and
request::Config.
The general rule is, if it is only used once then use the full name.
But there are so many line attributes that using the slightly shortened
form made it more readable.

> > +
> > +    let value = request.value(line_offset)?;
> > +    println!("{:?}", value);
> 
> Could also be:
> +    println!("{value:?}");
> (same below)
> 

Fair enough.  I'm old school so I tend to prefer printf style.

> > +                "line: {}, type: {}, event #{}",
> > +                event.line_offset(),
> > +                match event.event_type()? {
> > +                    line::EdgeKind::Rising => "Rising ",
> > +                    line::EdgeKind::Falling => "Falling",
> > +                },
> > +                event.line_seqno()
> > +            );
> 
> println!("{: <8}") could also be used to pad things (would allow
> removing the trailing space).
> 

So add 4 chars to remove 1?

Ideally the padding would go after the comma, and then you start getting
into compound fields, so this was a case of KISS.

Cheers,
Kent.
Erik Schilling June 14, 2023, 8:29 a.m. UTC | #3
On Wed Jun 14, 2023 at 10:18 AM CEST, Kent Gibson wrote:
> On Wed, Jun 14, 2023 at 09:52:20AM +0200, Erik Schilling wrote:
> > On Wed Jun 14, 2023 at 5:54 AM CEST, Kent Gibson wrote:
> > > Add rust equivalents of the core examples.
> > >
> > > Signed-off-by: Kent Gibson <warthog618@gmail.com>
> > 
> > Reviewed-by: Erik Schilling <erik.schilling@linaro.org>
> > 
> > Some nit-picks below, but those are a matter of taste and the change
> > looks ok either way.
> > 
> > > +
> > > +use libgpiod::line;
> > 
> > I think one could also just import the other used modules. Or, since
> > this is an example anyway, just `use libgpiod::*`.
> > 
>
> I'm never keen on using `::*`, as subsequent changes could pull in symbols
> that conflict with locals.
>
> And as this is an example I wanted to be explicit as to where the symbols
> originate, especially as there is some overlap, e.g. line::Config and
> request::Config.
> The general rule is, if it is only used once then use the full name.
> But there are so many line attributes that using the slightly shortened
> form made it more readable.

Yeah, I assumed that you followed this rule. Fine with me.

> > > +                "line: {}, type: {}, event #{}",
> > > +                event.line_offset(),
> > > +                match event.event_type()? {
> > > +                    line::EdgeKind::Rising => "Rising ",
> > > +                    line::EdgeKind::Falling => "Falling",
> > > +                },
> > > +                event.line_seqno()
> > > +            );
> > 
> > println!("{: <8}") could also be used to pad things (would allow
> > removing the trailing space).
> > 
>
> So add 4 chars to remove 1?
>
> Ideally the padding would go after the comma, and then you start getting
> into compound fields, so this was a case of KISS.

As I said, may be a matter of taste. I am fine with either way (thats
why I already provided the Review tag). The extra " " just jumped
to my eye since with rustfmt it is not aligned in a way that made it
immediately obvious.

- Erik
diff mbox series

Patch

diff --git a/bindings/rust/libgpiod/examples/get_line_value.rs b/bindings/rust/libgpiod/examples/get_line_value.rs
new file mode 100644
index 0000000..732fb71
--- /dev/null
+++ b/bindings/rust/libgpiod/examples/get_line_value.rs
@@ -0,0 +1,28 @@ 
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
+//
+// Minimal example of reading a single line.
+
+use libgpiod::line;
+
+fn main() -> libgpiod::Result<()> {
+    // example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+    let line_offset = 5;
+
+    let mut lsettings = line::Settings::new()?;
+    lsettings.set_direction(line::Direction::Input)?;
+
+    let mut lconfig = line::Config::new()?;
+    lconfig.add_line_settings(&[line_offset], lsettings)?;
+
+    let mut rconfig = libgpiod::request::Config::new()?;
+    rconfig.set_consumer("get-line-value")?;
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+    let request = chip.request_lines(Some(&rconfig), &lconfig)?;
+
+    let value = request.value(line_offset)?;
+    println!("{:?}", value);
+    Ok(())
+}
diff --git a/bindings/rust/libgpiod/examples/toggle_line_value.rs b/bindings/rust/libgpiod/examples/toggle_line_value.rs
new file mode 100644
index 0000000..cd7038e
--- /dev/null
+++ b/bindings/rust/libgpiod/examples/toggle_line_value.rs
@@ -0,0 +1,43 @@ 
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
+//
+// Minimal example of toggling a single line.
+
+use libgpiod::line;
+use std::time::Duration;
+
+fn toggle_value(value: line::Value) -> line::Value {
+    match value {
+        line::Value::Active => line::Value::InActive,
+        line::Value::InActive => line::Value::Active,
+    }
+}
+
+fn main() -> libgpiod::Result<()> {
+    // example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+    let line_offset = 5;
+
+    let mut value = line::Value::Active;
+
+    let mut settings = line::Settings::new()?;
+    settings
+        .set_direction(line::Direction::Output)?
+        .set_output_value(value)?;
+
+    let mut lconfig = line::Config::new()?;
+    lconfig.add_line_settings(&[line_offset], settings)?;
+
+    let mut rconfig = libgpiod::request::Config::new()?;
+    rconfig.set_consumer("toggle-line-value")?;
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+    let mut req = chip.request_lines(Some(&rconfig), &lconfig)?;
+
+    loop {
+        println!("{:?}", value);
+        std::thread::sleep(Duration::from_secs(1));
+        value = toggle_value(value);
+        req.set_value(line_offset, value)?;
+    }
+}
diff --git a/bindings/rust/libgpiod/examples/watch_line_value.rs b/bindings/rust/libgpiod/examples/watch_line_value.rs
new file mode 100644
index 0000000..5a95b6a
--- /dev/null
+++ b/bindings/rust/libgpiod/examples/watch_line_value.rs
@@ -0,0 +1,50 @@ 
+// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
+// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>
+//
+// Minimal example of watching for edges on a single line.
+
+use libgpiod::line;
+use std::time::Duration;
+
+fn main() -> libgpiod::Result<()> {
+    // example configuration - customize to suit your situation
+    let chip_path = "/dev/gpiochip0";
+    let line_offset = 5;
+
+    let mut lsettings = line::Settings::new()?;
+    // assume a button connecting the pin to ground,
+    // so pull it up and provide some debounce.
+    lsettings
+        .set_edge_detection(Some(line::Edge::Both))?
+        .set_bias(Some(line::Bias::PullUp))?
+        .set_debounce_period(Duration::from_millis(10));
+
+    let mut lconfig = line::Config::new()?;
+    lconfig.add_line_settings(&[line_offset], lsettings)?;
+
+    let mut rconfig = libgpiod::request::Config::new()?;
+    rconfig.set_consumer("watch-line-value")?;
+
+    let chip = libgpiod::chip::Chip::open(&chip_path)?;
+    let request = chip.request_lines(Some(&rconfig), &lconfig)?;
+
+    // a larger buffer is an optimisation for reading bursts of events from the
+    // kernel, but that is not necessary in this case, so 1 is fine.
+    let mut buffer = libgpiod::request::Buffer::new(1)?;
+    loop {
+        // blocks until at least one event is available
+        let events = request.read_edge_events(&mut buffer)?;
+        for event in events {
+            let event = event?;
+            println!(
+                "line: {}, type: {}, event #{}",
+                event.line_offset(),
+                match event.event_type()? {
+                    line::EdgeKind::Rising => "Rising ",
+                    line::EdgeKind::Falling => "Falling",
+                },
+                event.line_seqno()
+            );
+        }
+    }
+}