{"action":"created","comment":{"url":"https://api.github.com/repos/diwic/alsa-rs/pulls/comments/56771061","id":56771061,"diff_hunk":"@@ -0,0 +1,428 @@\n+//! Mixer API - Simple Mixer API for mixer control\n+//!\n+use std::ffi::CString;\n+use std::{ptr, mem};\n+\n+use alsa;\n+use super::card;\n+use super::error::*;\n+\n+const SELEM_ID_SIZE: usize = 64;\n+\n+/// wraps [snd_mixer_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___mixer.html)\n+pub struct Mixer(*mut alsa::snd_mixer_t);\n+\n+impl Mixer {\n+    /// Creates a new iterator for a specific card using the cards index and\n+    /// using hw name, i.e. `hw:0`\n+    pub fn new(c: &card::Card) -> Result<Mixer> {\n+        let card = &CString::new(format!(\"hw:{}\", c.get_index())).unwrap();\n+        let mut mixer_handle = ptr::null_mut();\n+        try!(acheck!(snd_mixer_open(&mut mixer_handle, 0)));\n+        try!(acheck!(snd_mixer_attach(mixer_handle, card.as_ptr())));\n+        try!(acheck!(snd_mixer_selem_register(mixer_handle, ptr::null_mut(), ptr::null_mut())));\n+        try!(acheck!(snd_mixer_load(mixer_handle)));\n+        Ok(Mixer(mixer_handle))\n+    }\n+}\n+\n+/// Closes mixer and frees used resources\n+impl Drop for Mixer {\n+    fn drop(&mut self) {\n+        unsafe { alsa::snd_mixer_close(self.0) };\n+    }\n+}\n+\n+/// Wraps [snd_mixer_selem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html)\n+#[derive(Copy, Clone)]\n+pub struct Elem<'a>{\n+    handle: *mut alsa::snd_mixer_elem_t,\n+    mixer: &'a Mixer\n+}\n+\n+impl<'a> Elem<'a> {\n+    /// Checks if this element is null by checking if the handle is null\n+    pub fn is_null(&self) -> bool {\n+        self.handle == 0 as *mut alsa::snd_mixer_elem_t\n+    }\n+}\n+\n+\n+/// Iterator for all elements of mixer\n+#[derive(Copy, Clone)]\n+pub struct Iter<'a>{\n+    last_handle: *mut alsa::snd_mixer_elem_t,\n+    mixer: &'a Mixer\n+}\n+\n+impl<'a> Iter<'a> {\n+    pub fn new(m: &'a Mixer) -> Iter<'a> {\n+        Iter {\n+            last_handle: ptr::null_mut(),\n+            mixer: m\n+        }\n+    }\n+}\n+\n+impl<'a> Iterator for Iter<'a> {\n+    type Item = Elem<'a>;\n+\n+    fn next(&mut self) -> Option<Elem<'a>> {\n+        let elem = if self.last_handle.is_null() {\n+            unsafe { alsa::snd_mixer_first_elem(self.mixer.0) }\n+        } else {\n+            unsafe { alsa::snd_mixer_elem_next(self.last_handle) }\n+        };\n+\n+        if elem.is_null() {\n+            None\n+        } else {\n+            self.last_handle = elem;\n+            Some(Elem { handle: elem, mixer: self.mixer})\n+        }\n+    }\n+\n+}\n+\n+/// Wrapper for `snd_mixer_selem_id_t`, using array of hardcoded length\n+// #[derive(Copy, Clone)]\n+pub struct SelemId([u8; SELEM_ID_SIZE]);\n+\n+impl SelemId {\n+    /// Creates a new SelemId` of hardcoded size SELEM_ID_SIZE.\n+    /// This size is checked against `snd_mixer_selem_id_sizeof`\n+    pub fn new(elem: Elem) -> SelemId {\n+        // Create empty selem_id and fill from mixer\n+        let sid = SelemId::empty();\n+        unsafe { alsa::snd_mixer_selem_get_id(elem.handle, sid.as_ptr()) };\n+        sid\n+    }\n+\n+    /// Returns an empty (zeroed) SelemId. This id is not a useable id and need to be initialized\n+    /// like `SelemId::new()` does\n+    pub fn empty() -> SelemId {\n+        assert!(unsafe { alsa::snd_mixer_selem_id_sizeof() } as usize <= SELEM_ID_SIZE);\n+        // Create empty selem_id and fill from mixer\n+        SelemId(unsafe { mem::zeroed() })\n+    }\n+\n+    /// Convert SelemId into ``*mut *mut snd_mixer_selem_id_t` that the alsa call needs.\n+    /// See [snd_mixer_selem_id_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___simple_mixer.html)\n+    #[inline]\n+    pub fn as_ptr(&self) -> *mut alsa::snd_mixer_selem_id_t {\n+        self.0.as_ptr() as *const _ as *mut alsa::snd_mixer_selem_id_t\n+    }\n+}\n+\n+/// Wraps an Elem as a Selem\n+// #[derive(Copy, Clone)]\n+pub struct Selem<'a>(SelemId, Elem<'a>);\n+\n+impl<'a> Selem<'a> {\n+    /// Creates a Selem by wrapping `elem`.\n+    pub fn new(elem: Elem<'a>) -> Selem<'a> {\n+        Selem(SelemId::new(elem), elem)\n+    }\n+\n+    /// Creates a Selem by lookung for a specific selem by name given a mixer (of a card)\n+    pub fn find_by_name(mixer: &'a Mixer, name: &str) -> Result<Selem<'a>> {\n+        let sid = SelemId::empty();\n+        unsafe { alsa::snd_mixer_selem_id_set_index(sid.as_ptr(), 0) };\n+        unsafe { alsa::snd_mixer_selem_id_set_name(sid.as_ptr(), CString::new(name).unwrap().as_ptr()) };\n+        let elem = Elem { handle: unsafe { alsa::snd_mixer_find_selem(mixer.0, sid.as_ptr()) }, mixer: mixer};\n+\n+        if elem.is_null() {\n+            Err(Error::new(Some(stringify!(\"snd_mixer_find_selem\").into()), -1 as ::libc::c_int))\n+        } else {\n+            Ok(Selem::new(elem))\n+        }\n+    }\n+\n+    /// returns the elem of this selem\n+    pub fn get_elem(&self) -> Elem<'a> {","path":"src/mixer.rs","position":142,"original_position":142,"commit_id":"1a5d17ac5aee3e39b774ca5cd223804a04d4acff","original_commit_id":"1a5d17ac5aee3e39b774ca5cd223804a04d4acff","user":{"login":"diwic","id":9721510,"avatar_url":"https://avatars.githubusercontent.com/u/9721510?v=3","gravatar_id":"","url":"https://api.github.com/users/diwic","html_url":"https://github.com/diwic","followers_url":"https://api.github.com/users/diwic/followers","following_url":"https://api.github.com/users/diwic/following{/other_user}","gists_url":"https://api.github.com/users/diwic/gists{/gist_id}","starred_url":"https://api.github.com/users/diwic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diwic/subscriptions","organizations_url":"https://api.github.com/users/diwic/orgs","repos_url":"https://api.github.com/users/diwic/repos","events_url":"https://api.github.com/users/diwic/events{/privacy}","received_events_url":"https://api.github.com/users/diwic/received_events","type":"User","site_admin":false},"body":"For some elegance, we could implement Deref instead","created_at":"2016-03-20T20:14:27Z","updated_at":"2016-03-20T20:14:27Z","html_url":"https://github.com/diwic/alsa-rs/pull/4#discussion_r56771061","pull_request_url":"https://api.github.com/repos/diwic/alsa-rs/pulls/4","_links":{"self":{"href":"https://api.github.com/repos/diwic/alsa-rs/pulls/comments/56771061"},"html":{"href":"https://github.com/diwic/alsa-rs/pull/4#discussion_r56771061"},"pull_request":{"href":"https://api.github.com/repos/diwic/alsa-rs/pulls/4"}}},"pull_request":{"url":"https://api.github.com/repos/diwic/alsa-rs/pulls/4","id":63296453,"html_url":"https://github.com/diwic/alsa-rs/pull/4","diff_url":"https://github.com/diwic/alsa-rs/pull/4.diff","patch_url":"https://github.com/diwic/alsa-rs/pull/4.patch","issue_url":"https://api.github.com/repos/diwic/alsa-rs/issues/4","number":4,"state":"open","locked":false,"title":"implement basic iterator for simple mixer api","user":{"login":"lrbalt","id":10996,"avatar_url":"https://avatars.githubusercontent.com/u/10996?v=3","gravatar_id":"","url":"https://api.github.com/users/lrbalt","html_url":"https://github.com/lrbalt","followers_url":"https://api.github.com/users/lrbalt/followers","following_url":"https://api.github.com/users/lrbalt/following{/other_user}","gists_url":"https://api.github.com/users/lrbalt/gists{/gist_id}","starred_url":"https://api.github.com/users/lrbalt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lrbalt/subscriptions","organizations_url":"https://api.github.com/users/lrbalt/orgs","repos_url":"https://api.github.com/users/lrbalt/repos","events_url":"https://api.github.com/users/lrbalt/events{/privacy}","received_events_url":"https://api.github.com/users/lrbalt/received_events","type":"User","site_admin":false},"body":"@diwic could you review this first attempt? Am I handling unsafe calls correctly? \r\n\r\nNot meant for merging, just to get your review :-)","created_at":"2016-03-17T21:34:52Z","updated_at":"2016-03-20T20:14:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8d77daa7f7b848fb66e5b1c6941daf0fa14de06e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/diwic/alsa-rs/pulls/4/commits","review_comments_url":"https://api.github.com/repos/diwic/alsa-rs/pulls/4/comments","review_comment_url":"https://api.github.com/repos/diwic/alsa-rs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/diwic/alsa-rs/issues/4/comments","statuses_url":"https://api.github.com/repos/diwic/alsa-rs/statuses/1a5d17ac5aee3e39b774ca5cd223804a04d4acff","head":{"label":"lrbalt:mixer-interface","ref":"mixer-interface","sha":"1a5d17ac5aee3e39b774ca5cd223804a04d4acff","user":{"login":"lrbalt","id":10996,"avatar_url":"https://avatars.githubusercontent.com/u/10996?v=3","gravatar_id":"","url":"https://api.github.com/users/lrbalt","html_url":"https://github.com/lrbalt","followers_url":"https://api.github.com/users/lrbalt/followers","following_url":"https://api.github.com/users/lrbalt/following{/other_user}","gists_url":"https://api.github.com/users/lrbalt/gists{/gist_id}","starred_url":"https://api.github.com/users/lrbalt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lrbalt/subscriptions","organizations_url":"https://api.github.com/users/lrbalt/orgs","repos_url":"https://api.github.com/users/lrbalt/repos","events_url":"https://api.github.com/users/lrbalt/events{/privacy}","received_events_url":"https://api.github.com/users/lrbalt/received_events","type":"User","site_admin":false},"repo":{"id":53807490,"name":"alsa-rs","full_name":"lrbalt/alsa-rs","owner":{"login":"lrbalt","id":10996,"avatar_url":"https://avatars.githubusercontent.com/u/10996?v=3","gravatar_id":"","url":"https://api.github.com/users/lrbalt","html_url":"https://github.com/lrbalt","followers_url":"https://api.github.com/users/lrbalt/followers","following_url":"https://api.github.com/users/lrbalt/following{/other_user}","gists_url":"https://api.github.com/users/lrbalt/gists{/gist_id}","starred_url":"https://api.github.com/users/lrbalt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lrbalt/subscriptions","organizations_url":"https://api.github.com/users/lrbalt/orgs","repos_url":"https://api.github.com/users/lrbalt/repos","events_url":"https://api.github.com/users/lrbalt/events{/privacy}","received_events_url":"https://api.github.com/users/lrbalt/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lrbalt/alsa-rs","description":"Tiny but safe ALSA wrappers","fork":true,"url":"https://api.github.com/repos/lrbalt/alsa-rs","forks_url":"https://api.github.com/repos/lrbalt/alsa-rs/forks","keys_url":"https://api.github.com/repos/lrbalt/alsa-rs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lrbalt/alsa-rs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lrbalt/alsa-rs/teams","hooks_url":"https://api.github.com/repos/lrbalt/alsa-rs/hooks","issue_events_url":"https://api.github.com/repos/lrbalt/alsa-rs/issues/events{/number}","events_url":"https://api.github.com/repos/lrbalt/alsa-rs/events","assignees_url":"https://api.github.com/repos/lrbalt/alsa-rs/assignees{/user}","branches_url":"https://api.github.com/repos/lrbalt/alsa-rs/branches{/branch}","tags_url":"https://api.github.com/repos/lrbalt/alsa-rs/tags","blobs_url":"https://api.github.com/repos/lrbalt/alsa-rs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lrbalt/alsa-rs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lrbalt/alsa-rs/git/refs{/sha}","trees_url":"https://api.github.com/repos/lrbalt/alsa-rs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lrbalt/alsa-rs/statuses/{sha}","languages_url":"https://api.github.com/repos/lrbalt/alsa-rs/languages","stargazers_url":"https://api.github.com/repos/lrbalt/alsa-rs/stargazers","contributors_url":"https://api.github.com/repos/lrbalt/alsa-rs/contributors","subscribers_url":"https://api.github.com/repos/lrbalt/alsa-rs/subscribers","subscription_url":"https://api.github.com/repos/lrbalt/alsa-rs/subscription","commits_url":"https://api.github.com/repos/lrbalt/alsa-rs/commits{/sha}","git_commits_url":"https://api.github.com/repos/lrbalt/alsa-rs/git/commits{/sha}","comments_url":"https://api.github.com/repos/lrbalt/alsa-rs/comments{/number}","issue_comment_url":"https://api.github.com/repos/lrbalt/alsa-rs/issues/comments{/number}","contents_url":"https://api.github.com/repos/lrbalt/alsa-rs/contents/{+path}","compare_url":"https://api.github.com/repos/lrbalt/alsa-rs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lrbalt/alsa-rs/merges","archive_url":"https://api.github.com/repos/lrbalt/alsa-rs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lrbalt/alsa-rs/downloads","issues_url":"https://api.github.com/repos/lrbalt/alsa-rs/issues{/number}","pulls_url":"https://api.github.com/repos/lrbalt/alsa-rs/pulls{/number}","milestones_url":"https://api.github.com/repos/lrbalt/alsa-rs/milestones{/number}","notifications_url":"https://api.github.com/repos/lrbalt/alsa-rs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lrbalt/alsa-rs/labels{/name}","releases_url":"https://api.github.com/repos/lrbalt/alsa-rs/releases{/id}","deployments_url":"https://api.github.com/repos/lrbalt/alsa-rs/deployments","created_at":"2016-03-13T21:01:00Z","updated_at":"2016-03-13T21:01:01Z","pushed_at":"2016-03-20T19:15:36Z","git_url":"git://github.com/lrbalt/alsa-rs.git","ssh_url":"git@github.com:lrbalt/alsa-rs.git","clone_url":"https://github.com/lrbalt/alsa-rs.git","svn_url":"https://github.com/lrbalt/alsa-rs","homepage":null,"size":63,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"diwic:master","ref":"master","sha":"fbd2af5e3dcb64491205be28f2ccbaf5e912cef6","user":{"login":"diwic","id":9721510,"avatar_url":"https://avatars.githubusercontent.com/u/9721510?v=3","gravatar_id":"","url":"https://api.github.com/users/diwic","html_url":"https://github.com/diwic","followers_url":"https://api.github.com/users/diwic/followers","following_url":"https://api.github.com/users/diwic/following{/other_user}","gists_url":"https://api.github.com/users/diwic/gists{/gist_id}","starred_url":"https://api.github.com/users/diwic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diwic/subscriptions","organizations_url":"https://api.github.com/users/diwic/orgs","repos_url":"https://api.github.com/users/diwic/repos","events_url":"https://api.github.com/users/diwic/events{/privacy}","received_events_url":"https://api.github.com/users/diwic/received_events","type":"User","site_admin":false},"repo":{"id":37067520,"name":"alsa-rs","full_name":"diwic/alsa-rs","owner":{"login":"diwic","id":9721510,"avatar_url":"https://avatars.githubusercontent.com/u/9721510?v=3","gravatar_id":"","url":"https://api.github.com/users/diwic","html_url":"https://github.com/diwic","followers_url":"https://api.github.com/users/diwic/followers","following_url":"https://api.github.com/users/diwic/following{/other_user}","gists_url":"https://api.github.com/users/diwic/gists{/gist_id}","starred_url":"https://api.github.com/users/diwic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diwic/subscriptions","organizations_url":"https://api.github.com/users/diwic/orgs","repos_url":"https://api.github.com/users/diwic/repos","events_url":"https://api.github.com/users/diwic/events{/privacy}","received_events_url":"https://api.github.com/users/diwic/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/diwic/alsa-rs","description":"Tiny but safe ALSA wrappers","fork":false,"url":"https://api.github.com/repos/diwic/alsa-rs","forks_url":"https://api.github.com/repos/diwic/alsa-rs/forks","keys_url":"https://api.github.com/repos/diwic/alsa-rs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/diwic/alsa-rs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/diwic/alsa-rs/teams","hooks_url":"https://api.github.com/repos/diwic/alsa-rs/hooks","issue_events_url":"https://api.github.com/repos/diwic/alsa-rs/issues/events{/number}","events_url":"https://api.github.com/repos/diwic/alsa-rs/events","assignees_url":"https://api.github.com/repos/diwic/alsa-rs/assignees{/user}","branches_url":"https://api.github.com/repos/diwic/alsa-rs/branches{/branch}","tags_url":"https://api.github.com/repos/diwic/alsa-rs/tags","blobs_url":"https://api.github.com/repos/diwic/alsa-rs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/diwic/alsa-rs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/diwic/alsa-rs/git/refs{/sha}","trees_url":"https://api.github.com/repos/diwic/alsa-rs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/diwic/alsa-rs/statuses/{sha}","languages_url":"https://api.github.com/repos/diwic/alsa-rs/languages","stargazers_url":"https://api.github.com/repos/diwic/alsa-rs/stargazers","contributors_url":"https://api.github.com/repos/diwic/alsa-rs/contributors","subscribers_url":"https://api.github.com/repos/diwic/alsa-rs/subscribers","subscription_url":"https://api.github.com/repos/diwic/alsa-rs/subscription","commits_url":"https://api.github.com/repos/diwic/alsa-rs/commits{/sha}","git_commits_url":"https://api.github.com/repos/diwic/alsa-rs/git/commits{/sha}","comments_url":"https://api.github.com/repos/diwic/alsa-rs/comments{/number}","issue_comment_url":"https://api.github.com/repos/diwic/alsa-rs/issues/comments{/number}","contents_url":"https://api.github.com/repos/diwic/alsa-rs/contents/{+path}","compare_url":"https://api.github.com/repos/diwic/alsa-rs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/diwic/alsa-rs/merges","archive_url":"https://api.github.com/repos/diwic/alsa-rs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/diwic/alsa-rs/downloads","issues_url":"https://api.github.com/repos/diwic/alsa-rs/issues{/number}","pulls_url":"https://api.github.com/repos/diwic/alsa-rs/pulls{/number}","milestones_url":"https://api.github.com/repos/diwic/alsa-rs/milestones{/number}","notifications_url":"https://api.github.com/repos/diwic/alsa-rs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/diwic/alsa-rs/labels{/name}","releases_url":"https://api.github.com/repos/diwic/alsa-rs/releases{/id}","deployments_url":"https://api.github.com/repos/diwic/alsa-rs/deployments","created_at":"2015-06-08T13:09:08Z","updated_at":"2016-03-20T06:00:17Z","pushed_at":"2016-03-20T19:15:36Z","git_url":"git://github.com/diwic/alsa-rs.git","ssh_url":"git@github.com:diwic/alsa-rs.git","clone_url":"https://github.com/diwic/alsa-rs.git","svn_url":"https://github.com/diwic/alsa-rs","homepage":null,"size":45,"stargazers_count":3,"watchers_count":3,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/diwic/alsa-rs/pulls/4"},"html":{"href":"https://github.com/diwic/alsa-rs/pull/4"},"issue":{"href":"https://api.github.com/repos/diwic/alsa-rs/issues/4"},"comments":{"href":"https://api.github.com/repos/diwic/alsa-rs/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/diwic/alsa-rs/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/diwic/alsa-rs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/diwic/alsa-rs/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/diwic/alsa-rs/statuses/1a5d17ac5aee3e39b774ca5cd223804a04d4acff"}}}}