// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
/// Cross-platform device identifiers (HostId + backend-specific identifier string).
///
/// Ported from upstream `cpal::DeviceId` and its parsing/display behavior.
///|
pub suberror DeviceIdError {
UnsupportedPlatform
BackendSpecific(BackendSpecificError)
} derive(Debug, Eq)
///|
pub fn device_id_error_unsupported_platform() -> DeviceIdError {
UnsupportedPlatform
}
///|
pub fn device_id_error_backend_specific(description : String) -> DeviceIdError {
BackendSpecific(BackendSpecificError(description))
}
///|
pub fn DeviceIdError::to_string(self : DeviceIdError) -> String {
match self {
BackendSpecific(err) => err.to_string()
UnsupportedPlatform => "Device IDs are unsupported for this OS"
}
}
///|
pub struct DeviceId {
host_id : HostId
device_id : String
} derive(Debug, Eq)
///|
pub fn DeviceId::DeviceId(host_id : HostId, device_id : String) -> DeviceId {
{ host_id, device_id }
}
///|
pub fn DeviceId::new(host_id : HostId, device_id : String) -> DeviceId {
DeviceId(host_id, device_id)
}
///|
pub fn DeviceId::host_id(self : DeviceId) -> HostId {
self.host_id
}
///|
pub fn DeviceId::device_id(self : DeviceId) -> String {
self.device_id
}
///|
pub fn DeviceId::to_string(self : DeviceId) -> String {
"\{self.host_id.to_string()}:\{self.device_id}"
}
///|
pub fn DeviceId::from_string(s : String) -> DeviceId raise DeviceIdError {
let parts = Array::new()
for p in s.split(":") {
parts.push(p)
}
if parts.length() < 2 || parts[0].is_empty() {
raise BackendSpecific(
BackendSpecificError(
"Failed to parse device ID from: \{s}\nCheck if format matches \"host:device_id\"",
),
)
}
let host_id = match HostId::from_view(parts[0]) {
Some(h) => h
None => raise UnsupportedPlatform
}
let dev = StringBuilder::new()
for i = 1; i < parts.length(); i = i + 1 {
if i > 1 {
dev.write_char(':')
}
dev.write_stringview(parts[i])
}
if dev.is_empty() {
raise BackendSpecific(
BackendSpecificError(
"Failed to parse device ID from: \{s}\nCheck if format matches \"host:device_id\"",
),
)
}
DeviceId(host_id, dev.to_string())
}