Baby's first Rust with extra steps (XPC, launchd, and FFI)!

This page summarizes the projects mentioned and recommended in the original post on dev.to

Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
  • chkservice

    Discontinued Systemd units manager with ncurses, terminal interface

    I wondered if there was something similar to LaunchControl that could run in a terminal. I've used chkservice on Linux, but there seems to be no macOS equivalent. I've been dying for an excuse to learn a little bit of Rust (loved n+1 years in a row by the SO developer survey2) -- so this was my chance. Several months later I ended up with launchk. The rest of this post will go over: getting started, interfacing with launchd, a lot of macOS IPC bits, getting stuck, and a bunch of probably questionable Rust FFI stuff.

  • launchk

    Cursive TUI that queries XPC to peek at launchd state

    I wondered if there was something similar to LaunchControl that could run in a terminal. I've used chkservice on Linux, but there seems to be no macOS equivalent. I've been dying for an excuse to learn a little bit of Rust (loved n+1 years in a row by the SO developer survey2) -- so this was my chance. Several months later I ended up with launchk. The rest of this post will go over: getting started, interfacing with launchd, a lot of macOS IPC bits, getting stuck, and a bunch of probably questionable Rust FFI stuff.

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

  • rust-block

    Rust interface for Apple's C language extension of blocks.

    let block = ConcreteBlock::new(move |key: *const c_char, value: xpc_object_t| { unsafe { xpc_retain(value) }; let str_key = unsafe { CStr::from_ptr(key).to_string_lossy().to_string() }; let xpc_object: XPCObject = value.into(); map_refcell .borrow_mut() .insert(str_key, xpc_object.into()); true }); // https://github.com/SSheldon/rust-block#creating-blocks let block = block.copy(); let ok = unsafe { xpc_dictionary_apply(object.as_ptr(), &*block as *const _ as *mut _) };

  • Cursive

    A Text User Interface library for the Rust programming language

    I used Cursive because the view absractions were very easy to grok and get started with. Much of the visual layout was inspired by another TUI I use for managing Kubernetes clusters: k9s. I like the omnibox-style interface. It seems reasonable to encode all of the tricky-key-combos bits into one component, then have it send semantically meaningful updates (e.g. a command was submitted). Views can implement OmniboxSubscriber, and OmniboxSubscribedView is kind of a hack so I can go from &mut dyn View to &mut OmniboxSubscribedView (to have on_omnibox available):

  • k9s

    🐶 Kubernetes CLI To Manage Your Clusters In Style!

    I used Cursive because the view absractions were very easy to grok and get started with. Much of the visual layout was inspired by another TUI I use for managing Kubernetes clusters: k9s. I like the omnibox-style interface. It seems reasonable to encode all of the tricky-key-combos bits into one component, then have it send semantically meaningful updates (e.g. a command was submitted). Views can implement OmniboxSubscriber, and OmniboxSubscribedView is kind of a hack so I can go from &mut dyn View to &mut OmniboxSubscribedView (to have on_omnibox available):

  • rust-bindgen

    Automatically generates Rust FFI bindings to C (and some C++) libraries.

    Our goal is to focus on getting our minimal C example into a Rust project. As a newcomer, rust-analyzer was tremendously helpful for discovering functions and API surface. Get Rust from rustup. Afterwards, make a new directory, cargo init, then set up bindgen. Include the same headers as in the example C program in wrapper.h -- they are in the default search path and require no further setup (find where: xcrun --show-sdk-path).

  • tokio

    A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

    I chose a LinearLayout as my root container. Only one child can be focused at a time in a LinearLayout which seems reasonable: we invoke on_omnibox for only that child. tokio futures with an interval were used to keep polling the XPC endpoint that returned the list of services (so we can see things as they pop on or off).

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts