// Copyright 2020 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. use std::error; use std::fmt; use remain::sorted; use crate::control::{self, Control}; use crate::control_primitive; use crate::control_primitive::{Ctl, ElemId, ElemIface}; use crate::control_tlv::{self, ControlTLV}; pub type Result = std::result::Result; #[sorted] #[derive(Debug)] /// Possible errors that can occur in cros-alsa::card. pub enum Error { /// Failed to call AlsaControlAPI. AlsaControlAPI(control_primitive::Error), /// Error occurs in Control. Control(control::Error), /// Error occurs in ControlTLV. ControlTLV(control_tlv::Error), } impl error::Error for Error {} impl From for Error { fn from(err: control::Error) -> Error { Error::Control(err) } } impl From for Error { fn from(err: control_tlv::Error) -> Error { Error::ControlTLV(err) } } impl From for Error { fn from(err: control_primitive::Error) -> Error { Error::AlsaControlAPI(err) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use Error::*; match self { AlsaControlAPI(e) => write!(f, "{}", e), Control(e) => write!(f, "{}", e), ControlTLV(e) => write!(f, "{}", e), } } } /// `Card` represents a sound card. #[derive(Debug)] pub struct Card { handle: Ctl, name: String, } impl Card { /// Creates a `Card`. /// /// # Arguments /// /// * `card_name` - The sound card name, ex: sofcmlmax98390d. /// /// # Errors /// /// * If card_name is an invalid CString. /// * If snd_ctl_open() fails. pub fn new(card_name: &str) -> Result { let handle = Ctl::new(&format!("hw:{}", card_name))?; Ok(Card { name: card_name.to_owned(), handle, }) } /// Gets sound card name. pub fn name(&self) -> &str { &self.name } /// Creates a `Control` from control name. /// /// # Errors /// /// * If control name is an invalid CString. /// * If control does not exist. /// * If `Control` elem_type() mismatches the type of underlying mixer control. /// * If `Control` size() mismatches the number of value entries of underlying mixer control. pub fn control_by_name<'a, T: 'a>(&'a mut self, control_name: &str) -> Result where T: Control<'a>, { let id = ElemId::new(ElemIface::Mixer, control_name)?; Ok(T::from(&mut self.handle, id)?) } /// Creates a `ControlTLV` from control name. /// /// # Errors /// /// * If control name is an invalid CString. /// * If control does not exist. pub fn control_tlv_by_name<'a>(&'a mut self, control_name: &str) -> Result> { let id = ElemId::new(ElemIface::Mixer, control_name)?; Ok(ControlTLV::new(&mut self.handle, id)?) } }