Skip to main content

StudioClient

Struct StudioClient 

Source
pub struct StudioClient<T> { /* private fields */ }
Expand description

Errors returned by high-level client operations. High-level synchronous ZMK Studio RPC client.

The generic parameter T is any transport implementing Read + Write (for example crate::transport::serial::SerialTransport).

Implementations§

Source§

impl<T: Read + Write> StudioClient<T>

Source

pub fn new(io: T) -> Self

Examples found in repository?
examples/basic_example.rs (line 36)
21fn run() -> Result<(), Box<dyn Error>> {
22    let mut args = std::env::args().skip(1);
23    let Some(mode) = args.next() else {
24        print_usage();
25        return Ok(());
26    };
27
28    match mode.as_str() {
29        "serial" => {
30            #[cfg(feature = "serial")]
31            {
32                let Some(port) = args.next() else {
33                    print_usage();
34                    return Ok(());
35                };
36                let client = StudioClient::new(SerialTransport::open(&port)?);
37                run_example(client)
38            }
39            #[cfg(not(feature = "serial"))]
40            {
41                Err("built without `serial` feature".into())
42            }
43        }
44        "ble" => {
45            #[cfg(feature = "ble")]
46            {
47                let devices = StudioClient::<BluestTransport>::list_ble_devices()?;
48                if devices.is_empty() {
49                    return Err(
50                        "No Bluetooth keyboards found. Pair/connect your keyboard first.".into(),
51                    );
52                }
53                let device = &devices[0];
54                println!("Using BLE device: {}", device.display_name());
55
56                let client = StudioClient::new(BluestTransport::connect_device(&device.device_id)?);
57                run_example(client)
58            }
59            #[cfg(not(feature = "ble"))]
60            {
61                Err("built without `ble` feature".into())
62            }
63        }
64        _ => {
65            print_usage();
66            Ok(())
67        }
68    }
69}
Source

pub fn next_notification(&mut self) -> Option<Notification>

Returns the next queued notification, if any.

Source

pub fn read_notification_blocking( &mut self, ) -> Result<Notification, ClientError>

Blocks until a notification arrives and returns it.

Source

pub fn get_device_info(&mut self) -> Result<GetDeviceInfoResponse, ClientError>

Returns static device information.

Examples found in repository?
examples/basic_example.rs (line 72)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn get_lock_state(&mut self) -> Result<LockState, ClientError>

Returns the current Studio lock state.

Examples found in repository?
examples/basic_example.rs (line 74)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn reset_settings(&mut self) -> Result<bool, ClientError>

Resets settings on the device.

Returns the firmware-provided success boolean.

Source

pub fn list_all_behaviors(&mut self) -> Result<Vec<u32>, ClientError>

Lists behavior IDs available on the connected device.

Examples found in repository?
examples/basic_example.rs (line 76)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn get_behavior_details( &mut self, behavior_id: u32, ) -> Result<GetBehaviorDetailsResponse, ClientError>

Returns details for a behavior ID (name and parameter metadata).

Examples found in repository?
examples/basic_example.rs (line 79)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn get_keymap(&mut self) -> Result<Keymap, ClientError>

Returns the current keymap state from the device.

Examples found in repository?
examples/basic_example.rs (line 83)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn get_physical_layouts(&mut self) -> Result<PhysicalLayouts, ClientError>

Returns available physical layouts and the active layout index.

Examples found in repository?
examples/basic_example.rs (line 93)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn set_layer_binding( &mut self, layer_id: u32, key_position: i32, binding: BehaviorBinding, ) -> Result<(), ClientError>

Sets a raw behavior binding for a specific layer position.

Source

pub fn get_key_at( &mut self, layer_id: u32, key_position: i32, ) -> Result<Behavior, ClientError>

Reads a behavior from a specific layer/key position.

Examples found in repository?
examples/basic_example.rs (line 110)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn resolve_keymap(&mut self) -> Result<Vec<Vec<Behavior>>, ClientError>

Fetches the keymap and resolves every binding into a typed Behavior.

Returns a Vec of layers, each layer being a Vec<Behavior> matching the order of bindings in the keymap. It fetches the keymap once and converts all bindings in a single pass.

Source

pub fn set_key_at( &mut self, layer_id: u32, key_position: i32, behavior: Behavior, ) -> Result<(), ClientError>

Set a behavior at a specific layer/key position.

Persist with StudioClient::save_changes or revert with StudioClient::discard_changes.

Examples found in repository?
examples/basic_example.rs (lines 113-117)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn check_unsaved_changes(&mut self) -> Result<bool, ClientError>

Returns whether there are pending unsaved keymap/layout changes.

Examples found in repository?
examples/basic_example.rs (line 122)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn save_changes(&mut self) -> Result<(), ClientError>

Saves pending keymap/layout mutations made by methods like StudioClient::set_key_at.

After this succeeds, changes are persisted on the device.

Source

pub fn discard_changes(&mut self) -> Result<bool, ClientError>

Discards pending keymap/layout mutations made since the last save.

Returns true if there were pending changes and they were discarded.

Examples found in repository?
examples/basic_example.rs (line 125)
71fn run_example<T: Read + Write>(mut client: StudioClient<T>) -> Result<(), Box<dyn Error>> {
72    let info = client.get_device_info()?;
73    println!("Device: {}", info.name);
74    println!("Lock: {:?}", client.get_lock_state()?);
75
76    let behavior_ids = client.list_all_behaviors()?;
77    println!("Behavior count: {}", behavior_ids.len());
78    if let Some(first_behavior_id) = behavior_ids.first().copied() {
79        let details = client.get_behavior_details(first_behavior_id)?;
80        println!("First behavior: {} ({})", details.id, details.display_name);
81    }
82
83    let keymap = match client.get_keymap() {
84        Ok(keymap) => keymap,
85        Err(ClientError::Meta(_)) => {
86            println!("Keymap request denied (likely locked); press `&studio_unlock` then rerun.");
87            return Ok(());
88        }
89        Err(err) => return Err(Box::new(err)),
90    };
91    println!("Layers: {}", keymap.layers.len());
92
93    let layouts = client.get_physical_layouts()?;
94    println!(
95        "Physical layouts: {} (active index: {})",
96        layouts.layouts.len(),
97        layouts.active_layout_index
98    );
99
100    let Some(first_layer) = keymap.layers.first() else {
101        return Ok(());
102    };
103    if first_layer.bindings.is_empty() {
104        return Ok(());
105    }
106
107    let layer_id = first_layer.id;
108    let key_position = 0;
109
110    let before = client.get_key_at(layer_id, key_position)?;
111    println!("Before: {before:?}");
112
113    client.set_key_at(
114        layer_id,
115        key_position,
116        Behavior::KeyPress(HidUsage::from_encoded(Keycode::A.to_hid_usage())),
117    )?;
118    let after = client.get_key_at(layer_id, key_position)?;
119    println!("After:  {after:?}");
120
121    // Change management APIs.
122    let has_changes = client.check_unsaved_changes()?;
123    println!("Unsaved changes: {has_changes}");
124    if has_changes {
125        client.discard_changes()?;
126    }
127
128    Ok(())
129}
Source

pub fn set_active_physical_layout( &mut self, index: u32, ) -> Result<Keymap, ClientError>

Sets the active physical layout by index and returns the resulting keymap.

Source

pub fn move_layer( &mut self, start_index: u32, dest_index: u32, ) -> Result<Keymap, ClientError>

Moves a layer from start_index to dest_index and returns the updated keymap.

Source

pub fn add_layer(&mut self) -> Result<AddLayerResponseDetails, ClientError>

Adds a layer and returns firmware-provided details about the created layer.

Source

pub fn remove_layer(&mut self, layer_index: u32) -> Result<(), ClientError>

Removes a layer by index.

Source

pub fn restore_layer( &mut self, layer_id: u32, at_index: u32, ) -> Result<Layer, ClientError>

Restores a previously removed layer at a specific index.

Source

pub fn set_layer_props( &mut self, layer_id: u32, name: impl Into<String>, ) -> Result<(), ClientError>

Sets user-facing properties for a layer (currently just name).

Source§

impl StudioClient<SerialTransport>

Source

pub fn open_serial(path: &str) -> Result<Self, SerialTransportError>

Convenience constructor for opening a serial transport and wrapping it in a client.

Auto Trait Implementations§

§

impl<T> Freeze for StudioClient<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for StudioClient<T>
where T: RefUnwindSafe,

§

impl<T> Send for StudioClient<T>
where T: Send,

§

impl<T> Sync for StudioClient<T>
where T: Sync,

§

impl<T> Unpin for StudioClient<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for StudioClient<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for StudioClient<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.