1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //! This mod provides derive macros for cros_alsa::control.
6
7 use proc_macro::TokenStream;
8 use proc_macro2::Span;
9 use quote::quote;
10
11 use crate::common::{parse_cros_alsa_attr, CrosAlsaAttr};
12
13 /// The provide default implementation for `ControlOps`.
14 /// Users could hold `Ctl` and `ElemID` as `handle` and `id` in their control structure and use
15 /// `#[derive(ControlOps)]` macro to generate default load / save implementations.
impl_control_ops(ast: &syn::DeriveInput) -> TokenStream16 pub fn impl_control_ops(ast: &syn::DeriveInput) -> TokenStream {
17 let name = &ast.ident;
18 let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
19 let attrs = match parse_cros_alsa_attr(&ast.attrs) {
20 Ok(attrs) => attrs,
21 Err(e) => return e.to_compile_error().into(),
22 };
23 let path = match attrs.iter().find(|x| x.is_path()) {
24 Some(CrosAlsaAttr::Path(path)) => path.clone(),
25 None => syn::LitStr::new("cros_alsa", Span::call_site())
26 .parse()
27 .expect("failed to create a default path for derive macro: ControlOps"),
28 };
29 let gen = quote! {
30 impl #impl_generics #path::ControlOps #impl_generics for #name #ty_generics #where_clause {
31 fn load(&mut self) -> ::std::result::Result<<Self as #path::Control #impl_generics>::Item, #path::ControlError> {
32 Ok(<Self as #path::Control>::Item::load(self.handle, &self.id)?)
33 }
34 fn save(&mut self, val: <Self as #path::Control #impl_generics>::Item) -> ::std::result::Result<bool, #path::ControlError> {
35 Ok(<Self as #path::Control>::Item::save(self.handle, &self.id, val)?)
36 }
37 }
38 };
39 gen.into()
40 }
41