<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Shiva&#x27;s Webpage</title>
    <link rel="self" type="application/atom+xml" href="https://skran.xyz/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://skran.xyz"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-08-24T00:00:00+00:00</updated>
    <id>https://skran.xyz/atom.xml</id>
    <entry xml:lang="en">
        <title>Porting a 23-year-old C library to Rust</title>
        <published>2026-08-24T00:00:00+00:00</published>
        <updated>2026-08-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Shiva Kiran Koninty
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://skran.xyz/articles/gsoc-2026/"/>
        <id>https://skran.xyz/articles/gsoc-2026/</id>
        
        <content type="html" xml:base="https://skran.xyz/articles/gsoc-2026/">&lt;p&gt;As an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;summerofcode.withgoogle.com&#x2F;programs&#x2F;2026&#x2F;projects&#x2F;Q2pKYmUp&quot;&gt;accepted contributor&lt;&#x2F;a&gt; for
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;summerofcode.withgoogle.com&#x2F;&quot;&gt;Google Summer of Code&lt;&#x2F;a&gt; 2026, I worked on porting parts
of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gnu.org&#x2F;software&#x2F;libcdio&quot;&gt;GNU libcdio&lt;&#x2F;a&gt; to Rust.&lt;&#x2F;p&gt;
&lt;p&gt;This has achieved:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A new implementation of libcdio,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;libcdio-rs&quot;&gt;libcdio-rs&lt;&#x2F;a&gt;, that is thread safe,
memory safe and wrapped behind hard-to-misuse interfaces.&lt;&#x2F;li&gt;
&lt;li&gt;Bug fixes and thread safety improvements to the existing C library.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Two new crates formed as a result:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;libcdio-cli&quot;&gt;libcdio-cli&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;libcdio-rs&quot;&gt;libcdio-rs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this article, I share the approach and learnings I’ve had from this
experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-gnu-libcdio&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-gnu-libcdio&quot; aria-label=&quot;Anchor link for: what-is-gnu-libcdio&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
What is GNU libcdio?&lt;&#x2F;h2&gt;
&lt;p&gt;It’s a C library that provides several routines needed for programs
that wish to work with optical media such as CD&#x2F;DVD and
BluRay, notably by providing an OS agnostic interface.&lt;&#x2F;p&gt;
&lt;p&gt;A few prominent programs that use GNU libcdio include ffmpeg,
GNOME gvfs, mpv, KDE kiso, Kodi, Rufus and VLC.&lt;&#x2F;p&gt;
&lt;p&gt;The library’s first commit traces back to 2003. This is before Git,
as the project originally used &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Concurrent_Versions_System&quot;&gt;CVS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-port-it-to-rust&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-port-it-to-rust&quot; aria-label=&quot;Anchor link for: why-port-it-to-rust&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Why port it to Rust?&lt;&#x2F;h2&gt;
&lt;p&gt;Rocky Bernstein, the author and maintainer of the project was annoyed
with the vulnerabilities reported due to memory management mistakes
and buffer overflows and chose Rust for renowned memory safety.&lt;&#x2F;p&gt;
&lt;p&gt;He believed that this would also fix up deeply rooted problems and
encourage the participation of the next generation of developers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scope-of-the-project&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#scope-of-the-project&quot; aria-label=&quot;Anchor link for: scope-of-the-project&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Scope of the project&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;libcdio’s SCSI MMC routines.&lt;&#x2F;li&gt;
&lt;li&gt;libcdio’s utility programs (four).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;porting-the-scsi-mmc-routines&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#porting-the-scsi-mmc-routines&quot; aria-label=&quot;Anchor link for: porting-the-scsi-mmc-routines&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Porting the SCSI MMC routines&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SCSI_Multimedia_Commands&quot;&gt;SCSI MMC&lt;&#x2F;a&gt; is a standard defining a command set for accessing
and controlling optical disc readers and writers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;initial-approach-rust-as-a-drop-in-c-replacement&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#initial-approach-rust-as-a-drop-in-c-replacement&quot; aria-label=&quot;Anchor link for: initial-approach-rust-as-a-drop-in-c-replacement&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Initial approach: Rust as a drop-in C replacement&lt;&#x2F;h3&gt;
&lt;p&gt;This involves making the Rust interfaces to be C compabible, so that
existing C code that used the library would continue to function,
while gaining the improvements brought upon by Rust.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;carols10cents&#x2F;rust-out-your-c-talk&quot;&gt;“Rust Out Your C”&lt;&#x2F;a&gt; by Carol Nichols is a good
resource on this.
&lt;img src=&quot;https:&#x2F;&#x2F;skran.xyz&#x2F;articles&#x2F;gsoc-2026&#x2F;c-rust-iter-loop.jpg#end&quot; alt=&quot;Rust to C iteration loop. Image taken from “Rust out your C” by Carol Nichols&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This comes with the cost of requiring the Rust toolchain to
build and use GNU libcdio.&lt;&#x2F;p&gt;
&lt;p&gt;With that, the first task was to figure out adding Rust to
its build system.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;rust-and-the-gnu-build-system&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#rust-and-the-gnu-build-system&quot; aria-label=&quot;Anchor link for: rust-and-the-gnu-build-system&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Rust and the GNU build system&lt;&#x2F;h4&gt;
&lt;p&gt;Being part of GNU, libcdio had naturally used the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;GNU_Autotools&quot;&gt;GNU build system&lt;&#x2F;a&gt;, which includes Autoconf,
Automake and Libtool.&lt;&#x2F;p&gt;
&lt;p&gt;These tools come from a very lively era that had a variety of Unices
and other Unix like operating systems. The only thing they all had
supported in common was the POSIX &lt;code&gt;make&lt;&#x2F;code&gt; command and shell scripts.&lt;&#x2F;p&gt;
&lt;p&gt;The GNU build system is kindof a hack that accepted a set of input
files which declared what the program needs such as certain C
libraries, headers and system features such as large file support
and produced a &lt;code&gt;configure&lt;&#x2F;code&gt; shell script that can runs on any
system. Its task is to probe the system for the program’s requirements
and produce a &lt;code&gt;Makefile&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The GNU manuals were helpful in understanding them.&lt;&#x2F;p&gt;
&lt;p&gt;I chose an approach where Cargo would handle just the Rust bits
and produce a static, C-compatible library, which the existing build
system can use to link against the C bits.&lt;&#x2F;p&gt;
&lt;p&gt;The article
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;viruta.org&#x2F;librsvgs-build-infrastructure-autotools-and-rust.html&quot;&gt;“Librsvg’s build infrastructure: Rust and Autotools”&lt;&#x2F;a&gt;
by Federico Mena Quintero was a strong inspiration.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libcdio&#x2F;libcdio&#x2F;pull&#x2F;49&quot;&gt;“build: Add Rust”&lt;&#x2F;a&gt; is the pull request incorporating this.&lt;&#x2F;p&gt;
&lt;p&gt;However, the users did not agree with the proposal, primarily due
to concerns about Rust’s relatively limited compiler ecosystem,
compared to C.&lt;&#x2F;p&gt;
&lt;p&gt;After a bit of discussion, I went with a change of approach.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;final-approach-a-separate-rust-library&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#final-approach-a-separate-rust-library&quot; aria-label=&quot;Anchor link for: final-approach-a-separate-rust-library&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Final approach: A separate Rust library&lt;&#x2F;h3&gt;
&lt;p&gt;This has the advantage of unlocking the full capabilities and
benefits of Rust, as there won’t be any constraints associated with
having a C-compatible interface.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;libcdio-rs-the-rust-implementation-of-gnu-libcdio&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#libcdio-rs-the-rust-implementation-of-gnu-libcdio&quot; aria-label=&quot;Anchor link for: libcdio-rs-the-rust-implementation-of-gnu-libcdio&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
libcdio-rs: The Rust implementation of GNU libcdio&lt;&#x2F;h4&gt;
&lt;p&gt;Implementing the SCSI MMC commands in Rust involved communicating with
a disc drive in binary:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Constructing requests per the SCSI and MMC specifications&lt;&#x2F;li&gt;
&lt;li&gt;Passing them to the OS specific device interface (such as &lt;code&gt;ioctl()&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Parsing binary responses&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The OS specific interfaces were abstracted by libcdio’s
&lt;code&gt;mmc_run_cmd()&lt;&#x2F;code&gt; function, which I’d re-used via FFI.&lt;&#x2F;p&gt;
&lt;p&gt;Parsing binary responses were done using the &lt;code&gt;winnow&lt;&#x2F;code&gt; crate’s
routines, which are designed to make these tasks less prone to human
error.&lt;&#x2F;p&gt;
&lt;p&gt;Every function had a unit test, which were performed on a USB based
CD&#x2F;DVD drive.&lt;&#x2F;p&gt;
&lt;p&gt;Rust’s idioms, such as the newtype pattern, were applied where
possible.&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;Example: An instance of using the newtype pattern&lt;&#x2F;summary&gt;
&lt;p&gt;There are routines that take a track number as input.
However, track numbers, per the spec are valid only from 1 to 100.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s a newtype &lt;code&gt;TrackNumber&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Track number.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Values must be between 1 and 99.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Use [`TrackNumber::try_from`] to construct a new value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span&gt; TrackNumber(u8);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt; TryFrom&amp;lt;u8&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; TrackNumber {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span&gt; Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; InvalidTrackNumber;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Construct `Self` from given track number.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; # Errors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; If the track number not within the range of 1 to 99, inclusive.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; try_from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;track_number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; u8)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Result&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; Self::&lt;&#x2F;span&gt;&lt;span&gt;Error&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;..=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;99&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;contains&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;track_number&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Ok(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;track_number&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Err(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;InvalidTrackNumber&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;track_number&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[derive(Debug, Error)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[error(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;invalid track number &amp;#39;{0}&amp;#39;; value must be between 1 and 99&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span&gt; InvalidTrackNumber(u8);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt; Default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; TrackNumber {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; -&amp;gt; Self&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;        Self&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt; 
&lt;p&gt;Routines that accept a track number now have a compile-time guarantee
of track numbers being within range:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Get the International Standard Recording Code (ISRC) of given track number.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;pub fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; isrc&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;&amp;amp;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; track_number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; TrackNumber)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Result&amp;lt;Option&amp;lt;String&amp;gt;, MmcSubchannelError&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; use track_number confidently, without any checks!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It also removes the need to verify track number inputs at every
routine (and having to define an error).&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;Example: Implementing SCSI MMC `START STOP UNIT`&lt;&#x2F;summary&gt;
&lt;p&gt;The &lt;code&gt;START STOP UNIT&lt;&#x2F;code&gt; command is used to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Eject or Close&#x2F;Open the tray of a drive&lt;&#x2F;li&gt;
&lt;li&gt;Set the drive to a power state such as idle, poweroff or sleep&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here’s the existing C implementation of this command from libcdio:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;   Load or Unload media using a SCSI-MMC START&#x2F;STOP UNIT command.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;   @param&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;font-style: italic;&quot;&gt; p_cdio&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;  the CD object to be acted upon.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;   @param&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;font-style: italic;&quot;&gt; b_eject&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; eject if true and close tray if false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;   @param&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;font-style: italic;&quot;&gt; b_immediate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; wait or don&amp;#39;t wait for operation to complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;   @param&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;font-style: italic;&quot;&gt; power_condition&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; Set CD-ROM to idle&#x2F;standby&#x2F;sleep. If nonzero,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;          eject&#x2F;load is ignored, so set to 0 if you want to eject or load.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    @see&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; mmc_eject_media or mmc_close_tray&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;driver_return_code_t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;mmc_start_stop_unit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; CdIo_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;p_cdio&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt; b_eject&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt; b_immediate&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;                    uint8_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt; power_condition&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; unsigned int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt; i_timeout_ms&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;  uint8_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; buf&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;  void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; p_buf &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;buf;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; unsigned int&lt;&#x2F;span&gt;&lt;span&gt; i_size &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;  MMC_CMD_SETUP&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;(CDIO_MMC_GPCMD_START_STOP_UNIT)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;  &#x2F;* this command doesn&amp;#39;t have an allocation length in its CDB *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; (b_immediate)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; cdb&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; (power_condition)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;    cdb&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; power_condition &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (b_eject)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;      cdb&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; &#x2F;* eject *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;      cdb&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;field&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; &#x2F;* close tray for tray-type *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; MMC_RUN_CMD&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;(SCSI_MMC_DATA_WRITE, mmc_timeout_ms)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One problem here is the reliance on human judgement to set
&lt;code&gt;power_condition&lt;&#x2F;code&gt; to zero for &lt;code&gt;b_eject&lt;&#x2F;code&gt; to not be ignored.&lt;&#x2F;p&gt;
&lt;p&gt;Rust algebraic types helped eliminate the invalid input of having both eject
and power condition being set.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, the exhaustive pattern matching also ensures that all
possible values are handled (such as &lt;code&gt;StartDisc&lt;&#x2F;code&gt;, &lt;code&gt;Jump&lt;&#x2F;code&gt;,
which the C implementation missed).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Operations of the `START STOP UNIT` command&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt; StartStopOperation {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    StopDisc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    StartDisc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    EjectDisc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    LoadStartDisc,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Change the online format-layer to the specified value for hybrid discs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Only the last two bits will be set.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Jump {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        layer_number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; u8,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; Place the device in the specified power condition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;    Power&lt;&#x2F;span&gt;&lt;span&gt;(PowerCondition),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; A power state as defined under MMC `START STOP UNIT`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span&gt; PowerCondition {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Idle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0x2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Standby&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0x3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Sleep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0x5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span&gt; Mmc {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; start_stop_unit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;&amp;amp;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; StartStopOperation)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; Result&amp;lt;(), MmcStartStopError&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; cdb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Cdb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        cdb&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; MmcCommand&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;StartStopUnit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; u8;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        cdb&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; &#x2F;&#x2F; not using the immediate bit for now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; let&lt;&#x2F;span&gt;&lt;span&gt; StartStopOperation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Jump {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; layer_number&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;            cdb&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; layer_number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; LAYER_NUM_BITMASK&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;            cdb&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; FORMAT_LAYER_BITPOS&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Sets the LoEj and Start fields&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        &#x2F;&#x2F; as described in 6.42.3.1 of MMC-6 2g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        cdb&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            StartStopOperation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;StartDisc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0b01&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            StartStopOperation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;EjectDisc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0b10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            StartStopOperation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;LoadStartDisc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; StartStopOperation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Jump {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; ..&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0b11&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;            _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 0b00&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; let&lt;&#x2F;span&gt;&lt;span&gt; StartStopOperation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;Power&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;pow_cond&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; operation&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;            cdb&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;pow_cond&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; u8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; POWER_COND_BITMASK&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; POWER_COND_BITPOS&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;        self.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;run_command&lt;&#x2F;span&gt;&lt;span&gt;(Some(MmcDirection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Write),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; [],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; cdb&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Ok(())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt; Cdb&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [u8;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;h2 id=&quot;porting-the-utility-programs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#porting-the-utility-programs&quot; aria-label=&quot;Anchor link for: porting-the-utility-programs&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Porting the utility programs&lt;&#x2F;h2&gt;
&lt;p&gt;The utility programs were essentially a demonstration of the library
capabilities.&lt;&#x2F;p&gt;
&lt;p&gt;Designing a CLI program is pretty simple in Rust, thanks to the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;clap&quot;&gt;&lt;code&gt;clap&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; crate.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rust-cli.github.io&#x2F;book&#x2F;&quot;&gt;Command line apps in Rust&lt;&#x2F;a&gt; is a neat guide.&lt;&#x2F;p&gt;
&lt;p&gt;However, a wrapper is needed for these to-be-Rust binaries to interface
with the C library.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;libcdio-sys-raw-bindings-over-libcdio&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#libcdio-sys-raw-bindings-over-libcdio&quot; aria-label=&quot;Anchor link for: libcdio-sys-raw-bindings-over-libcdio&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
libcdio-sys: Raw bindings over libcdio&lt;&#x2F;h3&gt;
&lt;p&gt;The first layer in interacting with a C library is to have a &lt;code&gt;-sys&lt;&#x2F;code&gt;
crate, which provides raw Rust bindings, i.e &lt;code&gt;extern fn&lt;&#x2F;code&gt;s, &lt;code&gt;const&lt;&#x2F;code&gt;s,
&lt;code&gt;static&lt;&#x2F;code&gt;s and &lt;code&gt;struct&lt;&#x2F;code&gt;s for every type, value and function exposed
by the C library.&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;libcdio-sys&quot;&gt;libcdio-sys&lt;&#x2F;a&gt; already existed.
It used [bindgen][bindgen-guide] to generate the bindings from
libcdio’s public C headers at build time.&lt;&#x2F;p&gt;
&lt;p&gt;However, it depended on having libcdio’s headers installed in the
system, and also, did not support vendoring.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;adding-vendoring-support-to-libcdio-sys&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#adding-vendoring-support-to-libcdio-sys&quot; aria-label=&quot;Anchor link for: adding-vendoring-support-to-libcdio-sys&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Adding vendoring support to libcdio-sys&lt;&#x2F;h4&gt;
&lt;blockquote class=&quot;tip&quot;&gt;
	&lt;p class=&quot;alert-title&quot;&gt;
		&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;Tip&lt;&#x2F;p&gt;
	&lt;p&gt;Vendoring in Rust is a practice where a crate also includes
the underlying C library that it provides bindings for.&lt;&#x2F;p&gt;

&lt;&#x2F;blockquote&gt;
&lt;p&gt;Ideally, these programs should require minimum effort to be installed,
i.e a &lt;code&gt;cargo install&lt;&#x2F;code&gt; should suffice. Having to install the C library
separately from repositories, or worse, having to build it from source
is not encouraging.&lt;&#x2F;p&gt;
&lt;p&gt;Moreover, the versions of libcdio in distro repositories varied:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Fedora shipped &lt;code&gt;v2.1.0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Debian shipped &lt;code&gt;v2.2.0&lt;&#x2F;code&gt; (Newer than Fedora? 🧐)&lt;&#x2F;li&gt;
&lt;li&gt;Arch shipped &lt;code&gt;v2.3.0&lt;&#x2F;code&gt; (the latest, btw)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While libcdio’s interfaces did not change much, the safe wrapper
relied on bugfixes that were about to be introduced in the next
release, &lt;code&gt;v2.4.0&lt;&#x2F;code&gt;. Given the slow pace of distro packaging, one would
have to resort to building and installing libcdio from source to
be able to use the Rust packages.&lt;&#x2F;p&gt;
&lt;p&gt;Vendoring solves this by also building the C library alongside the
&lt;code&gt;-sys&lt;&#x2F;code&gt; crate.&lt;&#x2F;p&gt;
&lt;p&gt;The libgit2-inspired versioning scheme for the &lt;code&gt;libcdio-sys&lt;&#x2F;code&gt; crate
also allows users to have a fine grained control over the version
of the underlying C library.&lt;&#x2F;p&gt;
&lt;p&gt;A custom &lt;code&gt;config.h&lt;&#x2F;code&gt; was made with common values for the most supported
targets to replace the Autotools generated one, and the &lt;code&gt;cc&lt;&#x2F;code&gt; crate was
used to compile the C sources.&lt;&#x2F;p&gt;
&lt;p&gt;This was guarded behind a &lt;code&gt;vendored&lt;&#x2F;code&gt; feature, alongside an opt-out env
variable &lt;code&gt;LIBCDIO_NO_VENDOR&lt;&#x2F;code&gt;, due to the additive nature of Cargo’s
features that might set this anyway if another crate in the dependency
chain happen to enable it.&lt;&#x2F;p&gt;
&lt;p&gt;And finally the default behavior was updated to probe the system
first, and fall back to vendoring if that fails.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s the Pull Request: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libcdio&#x2F;libcdio-sys&#x2F;pull&#x2F;10&quot;&gt;libcdio-sys&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As always, Jon Gjengset’s
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=pePqWoTnSmQ&quot;&gt;“Crust of Rust: Build scripts and FFI”&lt;&#x2F;a&gt;
was very helpful.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;libcdio-rs-a-safe-rust-wrapper-over-libcdio&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#libcdio-rs-a-safe-rust-wrapper-over-libcdio&quot; aria-label=&quot;Anchor link for: libcdio-rs-a-safe-rust-wrapper-over-libcdio&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
libcdio-rs: A safe Rust wrapper over libcdio&lt;&#x2F;h3&gt;
&lt;p&gt;The raw Rust bindings provided by &lt;code&gt;-sys&lt;&#x2F;code&gt; crates are too cumbersome
for direct use.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, another layer abstracts the &lt;code&gt;-sys&lt;&#x2F;code&gt; crate:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Converts raw and C compatible types such as &lt;code&gt;c_int&lt;&#x2F;code&gt;, &lt;code&gt;*const  c_char&lt;&#x2F;code&gt;, and &lt;code&gt;CString&lt;&#x2F;code&gt; to standard Rust types such as
&lt;code&gt;i32&lt;&#x2F;code&gt;, &lt;code&gt;&amp;amp;str&lt;&#x2F;code&gt; and &lt;code&gt;String&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Encapsulates the C library’s functionality through a neat,
object-oriented interface.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Leverages Rust’s borrow checker to enforce memory safety.&lt;&#x2F;p&gt;
&lt;details&gt;
  &lt;summary&gt;Example: An ISO 9660 entry whose lifetime is tied to its
  parent filesystem instance&lt;&#x2F;summary&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; ISO 9660 file&#x2F;directory entry.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span&gt; IsoEntry&amp;lt;&amp;#39;a&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F; The parent ISO 9660 object&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;crate&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; iso&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;a Iso,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;crate&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; stat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; NonNull&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;iso9660_stat_s&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;details&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Handles memory management using the &lt;code&gt;Drop&lt;&#x2F;code&gt; trait, rather than
having to call destructors manually.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Miscellaneous things, such as exposing C emitted logs, for example
using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;tracing&quot;&gt;&lt;code&gt;tracing&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; crate.&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;summary&gt;Capturing libcdio&#x27;s C logs in Rust&lt;&#x2F;summary&gt;
&lt;p&gt;libcdio provided for setting a custom log handler, through the
&lt;code&gt;cdio_log_set_handler()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;* Set a custom log handler for libcdio.  The return value is the log&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;* handler being replaced.  If the provided parameter is NULL, then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;* the handler will be reset to the default handler.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;cdio_log_handler_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; cdio_log_set_handler&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;cdio_log_handler_t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt; new_handler&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;* This type defines the signature of a log handler.  For every&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;* message being logged, the handler will receive the log level and&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;* the message string.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;typedef void&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;cdio_log_handler_t&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;cdio_log_level_t&lt;&#x2F;span&gt;&lt;span&gt; level,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; char&lt;&#x2F;span&gt;&lt;span&gt; message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;[]&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This handler function would be called for every log produced by the
library and be provided with the log level and the message.&lt;&#x2F;p&gt;
&lt;p&gt;Thus, I defined an &lt;code&gt;extern &quot;C&quot; fn log_handler()&lt;&#x2F;code&gt; which translated
these logs to &lt;code&gt;tracing&lt;&#x2F;code&gt; via its macros passed it to the C library via
&lt;code&gt;init_logger()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Handle logs via tracing.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;extern&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; log_handler&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;level&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; cdio_log_level_t&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;: *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; c_char&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;is_null&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F; SAFETY: message is not null, and is backed by an array on the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;    &#x2F;&#x2F; caller&amp;#39;s stack.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; = unsafe&lt;&#x2F;span&gt;&lt;span&gt; { CStr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;from_ptr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;) };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; Ok(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;to_str&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #[allow(non_upper_case_globals)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; level&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cdio_log_level_t_CDIO_LOG_ASSERT &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; cdio_log_level_t_CDIO_LOG_ERROR &lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tracing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;error!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cdio_log_level_t_CDIO_LOG_WARN &lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tracing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;warn!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cdio_log_level_t_CDIO_LOG_INFO &lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tracing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;info!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tracing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;debug!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; Configures libcdio to emit tracing (or &amp;quot;log&amp;quot; crate) logs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F; This should be called before using any other methods.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;crate&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; init_logger&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    static&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; LOG_HANDLER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Once&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Once&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;    LOG_HANDLER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;call_once&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;|| unsafe&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        libcdio_sys&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;cdio_log_set_handler&lt;&#x2F;span&gt;&lt;span&gt;(Some(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;log_handler&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        &#x2F;&#x2F; libcdio doesn&amp;#39;t call our log handler unless its log level is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        &#x2F;&#x2F; appropriate. Since the current log level is chosen by log&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        &#x2F;&#x2F; subscribers, hack around by setting libcdio&amp;#39;s log level to debug.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        libcdio_sys&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;cdio_loglevel_default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cdio_log_level_t_CDIO_LOG_DEBUG;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To make sure logs are not missed, &lt;code&gt;init_logger()&lt;&#x2F;code&gt; must be called at
all entry points of the library such as constructors, so that the
handler gets set as early as possible.&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;improvements-to-the-c-library&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#improvements-to-the-c-library&quot; aria-label=&quot;Anchor link for: improvements-to-the-c-library&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Improvements to the C library&lt;&#x2F;h4&gt;
&lt;p&gt;As Rust code was calling C code, it has to depend on the C code
upholding certain things to be safe. Things such as reentrancy and
thread safety.&lt;&#x2F;p&gt;
&lt;p&gt;A few things were bypassed, such as the use of a &lt;code&gt;Mutex&lt;&#x2F;code&gt; at the Rust
side to temporaily fix the dangers from C code’s use of mutable
statics.&lt;&#x2F;p&gt;
&lt;p&gt;The C code was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libcdio&#x2F;libcdio&#x2F;pull&#x2F;57&quot;&gt;updated&lt;&#x2F;a&gt; to use reentrant variants
of functions, such as &lt;code&gt;strtok_r()&lt;&#x2F;code&gt; over &lt;code&gt;strtok()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libcdio&#x2F;libcdio&#x2F;pull&#x2F;52&quot;&gt;few places&lt;&#x2F;a&gt; were updated to use thread
locals over statics to uphold thread safety.&lt;&#x2F;p&gt;
&lt;p&gt;A few implementations were found to be incorrect according to spec,
which were also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libcdio&#x2F;libcdio&#x2F;pull&#x2F;56&quot;&gt;fixed&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-utility-programs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-utility-programs&quot; aria-label=&quot;Anchor link for: the-utility-programs&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
The utility programs&lt;&#x2F;h3&gt;
&lt;p&gt;libcdio has seven utility programs, out of which, I’d covered:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iso-read&lt;&#x2F;code&gt;: Extracts files from an ISO 9660 filesystem.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;iso-info&lt;&#x2F;code&gt;: Lists files and metadata of an ISO 9660 filesystem.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cd-drive&lt;&#x2F;code&gt;: Provides details and capabilities of a disc drive.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;mmc-tool&lt;&#x2F;code&gt;: Allows to issue SCSI MMC commands to a disc drive.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These were renamed to &lt;code&gt;iso-cp&lt;&#x2F;code&gt;, &lt;code&gt;iso-ls&lt;&#x2F;code&gt;, &lt;code&gt;drive-info&lt;&#x2F;code&gt; and &lt;code&gt;mmc-cli&lt;&#x2F;code&gt;,
since there were major changes in the inputs and outputs of these
programs and it also avoided a name collision.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;clap&quot;&gt;&lt;code&gt;clap&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; crate, designing the CLI
interface was simple and idiomatic in a way that is strongly typed.&lt;&#x2F;p&gt;
&lt;p&gt;And now that we had a safe wrapper over &lt;code&gt;libcdio-rs&lt;&#x2F;code&gt;, all that
remained was to plug in the CLI interface with the library routines.&lt;&#x2F;p&gt;
&lt;p&gt;The options and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libcdio&#x2F;libcdio-rs&#x2F;pull&#x2F;9&quot;&gt;outputs were improved&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-three-month-journey&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-three-month-journey&quot; aria-label=&quot;Anchor link for: a-three-month-journey&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
A three month journey&lt;&#x2F;h2&gt;
&lt;p&gt;This project has allowed me to expand my Rust expertise to the
domain of systems programming, a level that closer to hardware
than the back end domain that I was already familiar with.&lt;&#x2F;p&gt;
&lt;p&gt;Interpreting lengthy specification sheets and collaborating with
the community and other authors were all quite the experience.&lt;&#x2F;p&gt;
&lt;p&gt;GSoC has been very good program in getting familiar with
distributed model of open source development, and I highly recommend
it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
