<commit_before>//! The YAML parser. Here is where we convert the yaml in to commands to be
/// processed later.

use yaml_rust::Yaml;
use command::{Command, Session, SendKeys, Split, Layout, Window, Attach};

#[cfg(test)] use yaml_rust::{YamlLoader};

/// Here was pass in the parsed yaml and project name. The purpose of this main
/// loop is to build the stack of commands that are run to setup a users tmux
/// session.
///
/// yaml_string: The parsed yaml from the config file.
/// project_name: The name of the project.
pub fn main(yaml_string: &Vec<Yaml>, project_name: &String, daemonize: bool) -> Result<Vec<Command>, String> {
    let mut commands: Vec<Command> = vec!();

    // There should only be one doc but it's a vec so loop it.
    for doc in yaml_string {
        let root = match doc["root"].as_str() {
            Some(x) => Some(x.to_string()),
            None    => None
        };

        let windows = doc["windows"].as_vec().expect("No Windows have been defined.");

        for window in windows.iter() {
            match window {
                &Yaml::Hash(ref h)  => {
                    for (k, v) in h {
                        if v.as_hash().is_some() {
                            commands.push(Command::Window(Window{
                                    session_name: project_name.clone(),
                                    name: k.as_str().unwrap().to_string()
                            }));

                            if root.is_some() {
                              let r = root.clone().unwrap();
                              commands.push(Command::SendKeys(SendKeys{
                                  target: format!("{}:{}", project_name, k.as_str().unwrap().to_string()).to_string(),
                                  exec: format!("cd {}", r)
                              }));
                            };

                            commands.append(&mut try!(pane_matcher(&project_name, v, &root.clone(), k.as_str().unwrap().to_string())));
                        } else {
                            commands.push(Command::Window(Window{
                                session_name: project_name.clone(),
                                name: try!(k.as_str().ok_or_else(|| "Windows require being named in your config.").map(|x| x.to_string()))
                            }));

                            if root.is_some() {
                              let r = root.clone().unwrap();
                              commands.push(Command::SendKeys(SendKeys{
                                  target: format!("{}:{}", project_name, k.as_str().unwrap().to_string()).to_string(),
                                  exec: format!("cd {}", r)
                              }));
                            };

                            if v.as_str().is_some() {
                                commands.push(Command::SendKeys(SendKeys{
                                    target: format!("{}:{}", project_name, k.as_str().unwrap().to_string()).to_string(),
                                    exec: v.as_str().unwrap().to_string()
                                }));
                            }
                        }
                    }
                },
                &Yaml::String(ref s) => {
                    commands.push(Command::Window(Window{
                        session_name: project_name.clone(),
                        name: s.clone()
                    }));

                    if root.is_some() {
                      let r = root.clone().unwrap();
                      commands.push(Command::SendKeys(SendKeys{
                          target: format!("{}:{}", project_name, s).to_string(),
                          exec: format!("cd {}", r).to_string()
                      }));
                    };
                },
                &Yaml::Integer(ref s) => {
                    commands.push(Command::Window(Window{
                        session_name: project_name.clone(),
                        name: s.to_string()
                    }));

                    if root.is_some() {
                      let r = root.clone().unwrap();
                      commands.push(Command::SendKeys(SendKeys{
                          target: format!("{}:{}", project_name, s).to_string(),
                          exec: format!("cd {}", r).to_string()
                      }));
                    };
                },
                _ => panic!("Muxed config file formatting isn't recognized.")
            };
        };
    };

    if !daemonize { commands.push(Command::Attach(Attach{name: project_name.clone()})) };

    let (first, commands) = commands.split_first().unwrap();
    let mut remains = commands.to_vec();

    match first {
        &Command::Window(ref w) => {
            remains.insert(0, Command::Session(Session{
                name: project_name.clone(),
                window_name: w.name.clone()
            }));
        },
        _ => {}
    };

    Ok(remains)
}

/// Pane matcher is for breaking apart the panes. Splitting windows when needed
/// and executing commands as needed.
fn pane_matcher(session: &String, window: &Yaml, root: &Option<String>, window_name: String) -> Result<Vec<Command>, String> {
    let mut commands = vec!();
    let panes = window["panes"].as_vec().expect("Something is wrong with panes.");

    for (i, pane) in panes.iter().enumerate() {
        // For every pane, we need one less split.
        // ex. An existing window to become 2 panes, needs 1 split.
        if i < (panes.len()-1) {
            commands.push(Command::Split(Split{
                target: format!("{}:{}.{}", session, window_name, i).to_string(),
                root: root.clone()
            }));
        };
        // Execute given commands in each new pane after all splits are
        // complete.

        if pane.as_str().is_some() {
            commands.push(Command::SendKeys(SendKeys{
                target: format!("{}:{}.{}", session, window_name, i).to_string(),
                exec: pane.as_str().unwrap().to_string()
            }));
        }
    };

    // After all panes are split select the layout for the window
    if window["layout"].as_str().is_some() {
        let layout = window["layout"].as_str().expect("Bad layout").to_string();
        commands.push(Command::Layout(Layout{
            target: format!("{}:{}", session, window_name).to_string(),
            layout: layout
        }));
    };

    Ok(commands)
}

#[test]
pub fn expect_1_session() {
    let s = "---
windows: ['cargo', 'vim', 'git']
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Session(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_2_windows_from_array() {
    let s = "---
windows: ['cargo', 'vim', 'git']
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Window(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 2)
}

#[test]
pub fn expect_1_attach() {
    let s = "---
windows: ['cargo', 'vim', 'git']
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Attach(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_2_windows_with_mixed_type_names() {
    let s = "---
windows: [1, 'vim', 3]
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Window(_) => true,
        _ => false
    }).collect();
    assert_eq!(remains.len(), 2)
}

#[test]
pub fn expect_2_windows_from_list() {
    let s = "---
windows:
  - cargo: ''
  - vim: ''
  - git: ''
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Window(_) => true,
        _ => false
    }).collect();
    assert_eq!(remains.len(), 2)
}

#[test]
pub fn expect_ok_with_empty_syscommands() {
    let s = "---
windows:
  - editor:
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let result = main(&yaml, &"muxed".to_string(), false);
    assert!(result.is_ok())
}

#[test]
pub fn expect_no_send_keys_commands() {
    let s = "---
windows:
  - editor:
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::SendKeys(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 0)
}

#[test]
pub fn expect_err_with_nameless_window() {
    let s = "---
windows:
  - : ls
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let result = main(&yaml, &"muxed".to_string(), false);
    assert!(result.is_err())
}

#[test]
pub fn expect_ok_with_empty_panes_syscommands() {
    let s = "---
windows:
  - cargo:
      layout: 'main-vertical'
      panes:
        -
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let result = main(&yaml, &"muxed".to_string(), false);
    assert!(result.is_ok())
}

#[test]
pub fn expect_no_send_keys_with_empty_panes_syscommands() {
    let s = "---
windows:
  - editor:
      panes:
        -
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::SendKeys(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 0)
}

#[test]
pub fn expect_1_split_window() {
    let s = "---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Split(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_1_layout() {
    let s = "---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Layout(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_1_session_with_panes_array() {
    let s = "---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Session(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}
<commit_msg>Not specifying a layout is a valid config.<commit_after>//! The YAML parser. Here is where we convert the yaml in to commands to be
/// processed later.

use yaml_rust::Yaml;
use command::{Command, Session, SendKeys, Split, Layout, Window, Attach};

#[cfg(test)] use yaml_rust::{YamlLoader};

/// Here was pass in the parsed yaml and project name. The purpose of this main
/// loop is to build the stack of commands that are run to setup a users tmux
/// session.
///
/// yaml_string: The parsed yaml from the config file.
/// project_name: The name of the project.
pub fn main(yaml_string: &Vec<Yaml>, project_name: &String, daemonize: bool) -> Result<Vec<Command>, String> {
    let mut commands: Vec<Command> = vec!();

    // There should only be one doc but it's a vec so loop it.
    for doc in yaml_string {
        let root = match doc["root"].as_str() {
            Some(x) => Some(x.to_string()),
            None    => None
        };

        let windows = doc["windows"].as_vec().expect("No Windows have been defined.");

        for window in windows.iter() {
            match window {
                &Yaml::Hash(ref h)  => {
                    for (k, v) in h {
                        if v.as_hash().is_some() {
                            commands.push(Command::Window(Window{
                                    session_name: project_name.clone(),
                                    name: k.as_str().unwrap().to_string()
                            }));

                            if root.is_some() {
                              let r = root.clone().unwrap();
                              commands.push(Command::SendKeys(SendKeys{
                                  target: format!("{}:{}", project_name, k.as_str().unwrap().to_string()).to_string(),
                                  exec: format!("cd {}", r)
                              }));
                            };

                            commands.append(&mut try!(pane_matcher(&project_name, v, &root.clone(), k.as_str().unwrap().to_string())));
                        } else {
                            commands.push(Command::Window(Window{
                                session_name: project_name.clone(),
                                name: try!(k.as_str().ok_or_else(|| "Windows require being named in your config.").map(|x| x.to_string()))
                            }));

                            if root.is_some() {
                              let r = root.clone().unwrap();
                              commands.push(Command::SendKeys(SendKeys{
                                  target: format!("{}:{}", project_name, k.as_str().unwrap().to_string()).to_string(),
                                  exec: format!("cd {}", r)
                              }));
                            };

                            if v.as_str().is_some() {
                                commands.push(Command::SendKeys(SendKeys{
                                    target: format!("{}:{}", project_name, k.as_str().unwrap().to_string()).to_string(),
                                    exec: v.as_str().unwrap().to_string()
                                }));
                            }
                        }
                    }
                },
                &Yaml::String(ref s) => {
                    commands.push(Command::Window(Window{
                        session_name: project_name.clone(),
                        name: s.clone()
                    }));

                    if root.is_some() {
                      let r = root.clone().unwrap();
                      commands.push(Command::SendKeys(SendKeys{
                          target: format!("{}:{}", project_name, s).to_string(),
                          exec: format!("cd {}", r).to_string()
                      }));
                    };
                },
                &Yaml::Integer(ref s) => {
                    commands.push(Command::Window(Window{
                        session_name: project_name.clone(),
                        name: s.to_string()
                    }));

                    if root.is_some() {
                      let r = root.clone().unwrap();
                      commands.push(Command::SendKeys(SendKeys{
                          target: format!("{}:{}", project_name, s).to_string(),
                          exec: format!("cd {}", r).to_string()
                      }));
                    };
                },
                _ => panic!("Muxed config file formatting isn't recognized.")
            };
        };
    };

    if !daemonize { commands.push(Command::Attach(Attach{name: project_name.clone()})) };

    let (first, commands) = commands.split_first().unwrap();
    let mut remains = commands.to_vec();

    match first {
        &Command::Window(ref w) => {
            remains.insert(0, Command::Session(Session{
                name: project_name.clone(),
                window_name: w.name.clone()
            }));
        },
        _ => {}
    };

    Ok(remains)
}

/// Pane matcher is for breaking apart the panes. Splitting windows when needed
/// and executing commands as needed.
fn pane_matcher(session: &String, window: &Yaml, root: &Option<String>, window_name: String) -> Result<Vec<Command>, String> {
    let mut commands = vec!();
    let panes = window["panes"].as_vec().expect("Something is wrong with panes.");

    for (i, pane) in panes.iter().enumerate() {
        // For every pane, we need one less split.
        // ex. An existing window to become 2 panes, needs 1 split.
        if i < (panes.len()-1) {
            commands.push(Command::Split(Split{
                target: format!("{}:{}.{}", session, window_name, i).to_string(),
                root: root.clone()
            }));
        };
        // Execute given commands in each new pane after all splits are
        // complete.

        if pane.as_str().is_some() {
            commands.push(Command::SendKeys(SendKeys{
                target: format!("{}:{}.{}", session, window_name, i).to_string(),
                exec: pane.as_str().unwrap().to_string()
            }));
        }
    };

    // After all panes are split select the layout for the window
    if window["layout"].as_str().is_some() {
        let err = format!("A problem with the specified layout for the window: {}", &window_name);
        let layout = window["layout"].as_str().expect(err.as_str()).to_string();
        commands.push(Command::Layout(Layout{
            target: format!("{}:{}", session, window_name).to_string(),
            layout: layout
        }));
    };

    Ok(commands)
}

#[test]
pub fn expect_1_session() {
    let s = "---
windows: ['cargo', 'vim', 'git']
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Session(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_2_windows_from_array() {
    let s = "---
windows: ['cargo', 'vim', 'git']
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Window(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 2)
}

#[test]
pub fn expect_1_attach() {
    let s = "---
windows: ['cargo', 'vim', 'git']
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Attach(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_2_windows_with_mixed_type_names() {
    let s = "---
windows: [1, 'vim', 3]
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Window(_) => true,
        _ => false
    }).collect();
    assert_eq!(remains.len(), 2)
}

#[test]
pub fn expect_2_windows_from_list() {
    let s = "---
windows:
  - cargo: ''
  - vim: ''
  - git: ''
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Window(_) => true,
        _ => false
    }).collect();
    assert_eq!(remains.len(), 2)
}

#[test]
pub fn expect_ok_with_empty_syscommands() {
    let s = "---
windows:
  - editor:
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let result = main(&yaml, &"muxed".to_string(), false);
    assert!(result.is_ok())
}

#[test]
pub fn expect_no_send_keys_commands() {
    let s = "---
windows:
  - editor:
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::SendKeys(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 0)
}

#[test]
pub fn expect_err_with_nameless_window() {
    let s = "---
windows:
  - : ls
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let result = main(&yaml, &"muxed".to_string(), false);
    assert!(result.is_err())
}

#[test]
pub fn expect_ok_with_empty_panes_syscommands() {
    let s = "---
windows:
  - cargo:
      layout: 'main-vertical'
      panes:
        -
";
    let yaml = YamlLoader::load_from_str(s).unwrap();
    let result = main(&yaml, &"muxed".to_string(), false);
    assert!(result.is_ok())
}

#[test]
pub fn expect_no_send_keys_with_empty_panes_syscommands() {
    let s = "---
windows:
  - editor:
      panes:
        -
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::SendKeys(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 0)
}

#[test]
pub fn expect_1_split_window() {
    let s = "---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Split(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_1_layout() {
    let s = "---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Layout(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_1_session_with_panes_array() {
    let s = "---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Session(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 1)
}

#[test]
pub fn expect_no_layout() {
    let s = "---
windows:
  - editor:
      panes: ['vim', 'guard']
";

    let yaml = YamlLoader::load_from_str(s).unwrap();
    let remains: Vec<Command> = main(&yaml, &"muxed".to_string(), false).unwrap().into_iter().filter(|x| match x {
        &Command::Layout(_) => true,
        _ => false
    }).collect();

    assert_eq!(remains.len(), 0)
}
<|endoftext|>


<commit_before>use libc;
use std;
use jack_sys as j;

/// A lock-free ringbuffer. The key attribute of a ringbuffer is that it can be safely accessed by two threads simultaneously,
/// one reading from the buffer and the other writing to it - without using any synchronization or mutual exclusion primitives.
/// For this to work correctly, there can only be a single reader and a single writer thread. Their identities cannot be interchanged.
///
/// # Example
/// ```
/// let ringbuf = RingBuffer::new(1024).unwrap();
/// let (mut reader, mut writer) = ringbuf.into_reader_writer();
///
/// let buf = [0u8, 1, 2, 3];
/// let num = writer.write_buffer(&buf);
/// assert_eq!(num, buf.len());
///
/// // Potentially in a another thread:
/// let mut outbuf = [0u8; 8];
/// let num = reader.read_buffer(&mut outbuf);
/// ```
pub struct RingBuffer(*mut j::jack_ringbuffer_t);

impl RingBuffer {
    /// Allocates a ringbuffer of a specified size.
    pub fn new(size: usize) -> Result<Self, ()> {

        let insize = size as libc::size_t;
        let handle = unsafe { j::jack_ringbuffer_create(insize) };

        if handle.is_null() {
            return Err(());
        }

        Ok(RingBuffer(handle))
    }

    /// Lock a ringbuffer data block into memory.
    pub fn mlock(&mut self) {
        unsafe { j::jack_ringbuffer_mlock(self.0) };
    }

    /// Resets the ring buffer, making an empty buffer. Not thread safe.
    pub fn reset(&mut self) {
        unsafe { j::jack_ringbuffer_reset(self.0) };
    }

    /// Create a reader and writer, to use the ring buffer.
    pub fn into_reader_writer(self) -> (RingBufferReader, RingBufferWriter) {
        let handle = std::sync::Arc::new(self);

        unsafe { (RingBufferReader::new(handle.clone()), RingBufferWriter::new(handle)) }
    }

    /// Re-create the ring buffer object from reader and writer. useful if you need to call reset.
    /// The reader and the writer pair must have been created from the same RingBuffer object.
    /// Not needed for deallocation, disposing of both reader and writer will deallocate buffer resources automatically.
    ///
    /// panics if the reader and the writer were created from different RingBuffer objects.
    pub fn from_reader_writer(r: RingBufferReader, w: RingBufferWriter) -> Self {
        let mut handle_r = r.into_handle();
        let handle_w = w.into_handle();

        if handle_r.0 != handle_w.0 {
            panic!("mismatching read and write handles!")
        }

        let handle = RingBuffer(handle_r.0);

        // make sure that get_mut works
        std::mem::drop(handle_w);
        let muthandle = std::sync::Arc::get_mut(&mut handle_r).unwrap();
        // make sure they don't close when they are dropped.
        muthandle.0 = std::ptr::null_mut();
        handle
    }
}

impl Drop for RingBuffer {
    fn drop(&mut self) {
        if !self.0.is_null() {
            unsafe { j::jack_ringbuffer_free(self.0) };
        }
        self.0 = 0 as *mut j::jack_ringbuffer_t;
    }
}

/// Read end of the ring buffer. Can only be used from one thread (can be different from the write thread).
pub struct RingBufferReader {
    ringbuffer_handle: std::sync::Arc<RingBuffer>,
}

unsafe impl Send for RingBufferReader {}
// impl !Sync for RingBufferReader{ }

/// Write end of the ring buffer. Can only be used from one thread (can be a different from the read thread).
pub struct RingBufferWriter {
    ringbuffer_handle: std::sync::Arc<RingBuffer>,
}

unsafe impl Send for RingBufferWriter {}
// impl !Sync for RingBufferWriter{ }

impl RingBufferReader {
    unsafe fn new(handle: std::sync::Arc<RingBuffer>) -> Self {
        RingBufferReader { ringbuffer_handle: handle }
    }

    fn into_handle(self) -> std::sync::Arc<RingBuffer> {
        self.ringbuffer_handle
    }

    /// Fill a data structure with a description of the current readable data held in the ringbuffer.
    /// This description is returned in a two slices. Two slices are needed because the data to be read may be split
    /// across the end of the ringbuffer. The first slice represents the bytes ready to be read. if the second slice
    // is not empty, it is the continuation of the data that ended in the first slices. For convienence, consider using
    // peek_iter instead.
    pub fn get_vector<'a>(&'a self) -> (&'a [u8], &'a [u8]) {
        let mut vec = [j::jack_ringbuffer_data_t::default(), j::jack_ringbuffer_data_t::default()];
        let vecstart = &mut vec[0] as *mut j::jack_ringbuffer_data_t;

        unsafe { j::jack_ringbuffer_get_read_vector(self.ringbuffer_handle.0, vecstart) };

        let view1 = vec[0];
        let view2 = vec[1];

        let buf1 = view1.buf as *mut u8;
        let len1 = view1.len as usize;

        let mut buf2 = view2.buf as *mut u8;
        let len2 = view2.len as usize;

        if len2 == 0 {
            // buf2 can't be null even if length is zero, so just use buf1
            buf2 = buf1;
        }

        let view1 = unsafe { std::slice::from_raw_parts(buf1, len1) };
        let view2 = unsafe { std::slice::from_raw_parts(buf2, len2) };
        (view1, view2)
    }

    /// Read data from the ringbuffer.
    /// Returns: the number of bytes read, which may range from 0 to buf.len().
    pub fn read_buffer(&mut self, buf: &mut [u8]) -> usize {
        if buf.len() == 0 {
            return 0;
        }

        let insize: libc::size_t = buf.len() as libc::size_t;
        let bufstart = &mut buf[0] as *mut _ as *mut libc::c_char;

        let read = unsafe { j::jack_ringbuffer_read(self.ringbuffer_handle.0, bufstart, insize) };
        read as usize
    }

    /// Read data from the ringbuffer. Opposed to read_buffer() this function does not move the read pointer.
    /// Thus it's a convenient way to inspect data in the ringbuffer in a continous fashion.
    /// The price is that the data is copied into a user provided buffer.
    /// For "raw" non-copy inspection of the data in the ringbuffer use get_vector() or peek_iter.
    /// Returns: the number of bytes read, which may range from 0 to buf.len()
    pub fn peek(&self, buf: &mut [u8]) -> usize {
        if buf.len() == 0 {
            return 0;
        }

        let insize: libc::size_t = buf.len() as libc::size_t;
        let bufstart = &mut buf[0] as *mut _ as *mut libc::c_char;

        let read = unsafe { j::jack_ringbuffer_peek(self.ringbuffer_handle.0, bufstart, insize) };
        read as usize
    }

    /// Advance the read pointer. use this after peek/peek_iter or get_vector to advance the buffer pointer.
    pub fn advance(&mut self, cnt: usize) {
        let incnt = cnt as libc::size_t;
        unsafe { j::jack_ringbuffer_read_advance(self.ringbuffer_handle.0, incnt) };
    }

    /// Return the number of bytes available for reading.
    pub fn space(&self) -> usize {
        unsafe { j::jack_ringbuffer_read_space(self.ringbuffer_handle.0) as usize }
    }

    /// Iterator that goes over all the data available to read.
    pub fn peek_iter<'a>
        (&'a self)
         -> std::iter::Chain<std::slice::Iter<'a, u8>, std::slice::Iter<'a, u8>> {

        let (view1, view2) = self.get_vector();

        view1.iter().chain(view2.iter())
    }
}

impl std::io::Read for RingBufferReader {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        Ok(self.read_buffer(buf))
    }
}

impl RingBufferWriter {
    unsafe fn new(handle: std::sync::Arc<RingBuffer>) -> Self {
        RingBufferWriter { ringbuffer_handle: handle }
    }

    fn into_handle(self) -> std::sync::Arc<RingBuffer> {
        self.ringbuffer_handle
    }

    /// Write data into the ringbuffer.
    /// Returns: The number of bytes written, which may range from 0 to buf.len()
    pub fn write_buffer(&mut self, buf: &[u8]) -> usize {
        if buf.len() == 0 {
            return 0;
        }

        let insize: libc::size_t = buf.len() as libc::size_t;
        let bufstart = &buf[0] as *const _ as *const libc::c_char;

        let read = unsafe { j::jack_ringbuffer_write(self.ringbuffer_handle.0, bufstart, insize) };
        read as usize
    }

    /// Advance the write pointer. use this after peek_iter or get_vector to advance the buffer pointer.
    pub fn advance(&mut self, cnt: usize) {
        let incnt = cnt as libc::size_t;
        unsafe { j::jack_ringbuffer_write_advance(self.ringbuffer_handle.0, incnt) };

    }

    /// Return the number of bytes available for writing.
    pub fn space(&mut self) -> usize {
        unsafe { j::jack_ringbuffer_write_space(self.ringbuffer_handle.0) as usize }
    }

    /// Return a pair of slices of the current writable space in the ringbuffer. two slices are needed because the space available for writing may be split across the end of the ringbuffer.
    /// consider using peek_iter for convience.
    pub fn get_vector<'a>(&'a mut self) -> (&'a mut [u8], &'a mut [u8]) {
        let mut vec = [j::jack_ringbuffer_data_t::default(), j::jack_ringbuffer_data_t::default()];
        let vecstart = &mut vec[0] as *mut j::jack_ringbuffer_data_t;

        unsafe { j::jack_ringbuffer_get_write_vector(self.ringbuffer_handle.0, vecstart) };

        let view1 = vec[0];
        let view2 = vec[1];

        let buf1 = view1.buf as *mut u8;
        let len1 = view1.len as usize;

        let mut buf2 = view2.buf as *mut u8;
        let len2 = view2.len as usize;

        if len2 == 0 {
            // buf2 can't be null even if length is zero, so just use buf1
            buf2 = buf1;
        }

        let view1 = unsafe { std::slice::from_raw_parts_mut(buf1, len1) };
        let view2 = unsafe { std::slice::from_raw_parts_mut(buf2, len2) };
        (view1, view2)
    }

    /// Iterator that goes over all the data available to write.
    pub fn peek_iter<'a>
        (&'a mut self)
         -> std::iter::Chain<std::slice::IterMut<'a, u8>, std::slice::IterMut<'a, u8>> {

        let (mut view1, mut view2) = self.get_vector();

        view1.iter_mut().chain(view2.iter_mut())
    }
}

impl std::io::Write for RingBufferWriter {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        Ok(self.write_buffer(buf))
    }

    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}
<commit_msg>Make doc example compile<commit_after>use libc;
use std;
use jack_sys as j;

/// A lock-free ringbuffer. The key attribute of a ringbuffer is that it can be safely accessed by two threads simultaneously,
/// one reading from the buffer and the other writing to it - without using any synchronization or mutual exclusion primitives.
/// For this to work correctly, there can only be a single reader and a single writer thread. Their identities cannot be interchanged.
///
/// # Example
/// ```
/// use jack::prelude as j;
/// let ringbuf = j::RingBuffer::new(1024).unwrap();
/// let (mut reader, mut writer) = ringbuf.into_reader_writer();
///
/// let buf = [0u8, 1, 2, 3];
/// let num = writer.write_buffer(&buf);
/// assert_eq!(num, buf.len());
///
/// // Potentially in a another thread:
/// let mut outbuf = [0u8; 8];
/// let num = reader.read_buffer(&mut outbuf);
/// ```
pub struct RingBuffer(*mut j::jack_ringbuffer_t);

impl RingBuffer {
    /// Allocates a ringbuffer of a specified size.
    pub fn new(size: usize) -> Result<Self, ()> {

        let insize = size as libc::size_t;
        let handle = unsafe { j::jack_ringbuffer_create(insize) };

        if handle.is_null() {
            return Err(());
        }

        Ok(RingBuffer(handle))
    }

    /// Lock a ringbuffer data block into memory.
    pub fn mlock(&mut self) {
        unsafe { j::jack_ringbuffer_mlock(self.0) };
    }

    /// Resets the ring buffer, making an empty buffer. Not thread safe.
    pub fn reset(&mut self) {
        unsafe { j::jack_ringbuffer_reset(self.0) };
    }

    /// Create a reader and writer, to use the ring buffer.
    pub fn into_reader_writer(self) -> (RingBufferReader, RingBufferWriter) {
        let handle = std::sync::Arc::new(self);

        unsafe { (RingBufferReader::new(handle.clone()), RingBufferWriter::new(handle)) }
    }

    /// Re-create the ring buffer object from reader and writer. useful if you need to call reset.
    /// The reader and the writer pair must have been created from the same RingBuffer object.
    /// Not needed for deallocation, disposing of both reader and writer will deallocate buffer resources automatically.
    ///
    /// panics if the reader and the writer were created from different RingBuffer objects.
    pub fn from_reader_writer(r: RingBufferReader, w: RingBufferWriter) -> Self {
        let mut handle_r = r.into_handle();
        let handle_w = w.into_handle();

        if handle_r.0 != handle_w.0 {
            panic!("mismatching read and write handles!")
        }

        let handle = RingBuffer(handle_r.0);

        // make sure that get_mut works
        std::mem::drop(handle_w);
        let muthandle = std::sync::Arc::get_mut(&mut handle_r).unwrap();
        // make sure they don't close when they are dropped.
        muthandle.0 = std::ptr::null_mut();
        handle
    }
}

impl Drop for RingBuffer {
    fn drop(&mut self) {
        if !self.0.is_null() {
            unsafe { j::jack_ringbuffer_free(self.0) };
        }
        self.0 = 0 as *mut j::jack_ringbuffer_t;
    }
}

/// Read end of the ring buffer. Can only be used from one thread (can be different from the write thread).
pub struct RingBufferReader {
    ringbuffer_handle: std::sync::Arc<RingBuffer>,
}

unsafe impl Send for RingBufferReader {}
// impl !Sync for RingBufferReader{ }

/// Write end of the ring buffer. Can only be used from one thread (can be a different from the read thread).
pub struct RingBufferWriter {
    ringbuffer_handle: std::sync::Arc<RingBuffer>,
}

unsafe impl Send for RingBufferWriter {}
// impl !Sync for RingBufferWriter{ }

impl RingBufferReader {
    unsafe fn new(handle: std::sync::Arc<RingBuffer>) -> Self {
        RingBufferReader { ringbuffer_handle: handle }
    }

    fn into_handle(self) -> std::sync::Arc<RingBuffer> {
        self.ringbuffer_handle
    }

    /// Fill a data structure with a description of the current readable data held in the ringbuffer.
    /// This description is returned in a two slices. Two slices are needed because the data to be read may be split
    /// across the end of the ringbuffer. The first slice represents the bytes ready to be read. if the second slice
    // is not empty, it is the continuation of the data that ended in the first slices. For convienence, consider using
    // peek_iter instead.
    pub fn get_vector<'a>(&'a self) -> (&'a [u8], &'a [u8]) {
        let mut vec = [j::jack_ringbuffer_data_t::default(), j::jack_ringbuffer_data_t::default()];
        let vecstart = &mut vec[0] as *mut j::jack_ringbuffer_data_t;

        unsafe { j::jack_ringbuffer_get_read_vector(self.ringbuffer_handle.0, vecstart) };

        let view1 = vec[0];
        let view2 = vec[1];

        let buf1 = view1.buf as *mut u8;
        let len1 = view1.len as usize;

        let mut buf2 = view2.buf as *mut u8;
        let len2 = view2.len as usize;

        if len2 == 0 {
            // buf2 can't be null even if length is zero, so just use buf1
            buf2 = buf1;
        }

        let view1 = unsafe { std::slice::from_raw_parts(buf1, len1) };
        let view2 = unsafe { std::slice::from_raw_parts(buf2, len2) };
        (view1, view2)
    }

    /// Read data from the ringbuffer.
    /// Returns: the number of bytes read, which may range from 0 to buf.len().
    pub fn read_buffer(&mut self, buf: &mut [u8]) -> usize {
        if buf.len() == 0 {
            return 0;
        }

        let insize: libc::size_t = buf.len() as libc::size_t;
        let bufstart = &mut buf[0] as *mut _ as *mut libc::c_char;

        let read = unsafe { j::jack_ringbuffer_read(self.ringbuffer_handle.0, bufstart, insize) };
        read as usize
    }

    /// Read data from the ringbuffer. Opposed to read_buffer() this function does not move the read pointer.
    /// Thus it's a convenient way to inspect data in the ringbuffer in a continous fashion.
    /// The price is that the data is copied into a user provided buffer.
    /// For "raw" non-copy inspection of the data in the ringbuffer use get_vector() or peek_iter.
    /// Returns: the number of bytes read, which may range from 0 to buf.len()
    pub fn peek(&self, buf: &mut [u8]) -> usize {
        if buf.len() == 0 {
            return 0;
        }

        let insize: libc::size_t = buf.len() as libc::size_t;
        let bufstart = &mut buf[0] as *mut _ as *mut libc::c_char;

        let read = unsafe { j::jack_ringbuffer_peek(self.ringbuffer_handle.0, bufstart, insize) };
        read as usize
    }

    /// Advance the read pointer. use this after peek/peek_iter or get_vector to advance the buffer pointer.
    pub fn advance(&mut self, cnt: usize) {
        let incnt = cnt as libc::size_t;
        unsafe { j::jack_ringbuffer_read_advance(self.ringbuffer_handle.0, incnt) };
    }

    /// Return the number of bytes available for reading.
    pub fn space(&self) -> usize {
        unsafe { j::jack_ringbuffer_read_space(self.ringbuffer_handle.0) as usize }
    }

    /// Iterator that goes over all the data available to read.
    pub fn peek_iter<'a>
        (&'a self)
         -> std::iter::Chain<std::slice::Iter<'a, u8>, std::slice::Iter<'a, u8>> {

        let (view1, view2) = self.get_vector();

        view1.iter().chain(view2.iter())
    }
}

impl std::io::Read for RingBufferReader {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        Ok(self.read_buffer(buf))
    }
}

impl RingBufferWriter {
    unsafe fn new(handle: std::sync::Arc<RingBuffer>) -> Self {
        RingBufferWriter { ringbuffer_handle: handle }
    }

    fn into_handle(self) -> std::sync::Arc<RingBuffer> {
        self.ringbuffer_handle
    }

    /// Write data into the ringbuffer.
    /// Returns: The number of bytes written, which may range from 0 to buf.len()
    pub fn write_buffer(&mut self, buf: &[u8]) -> usize {
        if buf.len() == 0 {
            return 0;
        }

        let insize: libc::size_t = buf.len() as libc::size_t;
        let bufstart = &buf[0] as *const _ as *const libc::c_char;

        let read = unsafe { j::jack_ringbuffer_write(self.ringbuffer_handle.0, bufstart, insize) };
        read as usize
    }

    /// Advance the write pointer. use this after peek_iter or get_vector to advance the buffer pointer.
    pub fn advance(&mut self, cnt: usize) {
        let incnt = cnt as libc::size_t;
        unsafe { j::jack_ringbuffer_write_advance(self.ringbuffer_handle.0, incnt) };

    }

    /// Return the number of bytes available for writing.
    pub fn space(&mut self) -> usize {
        unsafe { j::jack_ringbuffer_write_space(self.ringbuffer_handle.0) as usize }
    }

    /// Return a pair of slices of the current writable space in the ringbuffer. two slices are needed because the space available for writing may be split across the end of the ringbuffer.
    /// consider using peek_iter for convience.
    pub fn get_vector<'a>(&'a mut self) -> (&'a mut [u8], &'a mut [u8]) {
        let mut vec = [j::jack_ringbuffer_data_t::default(), j::jack_ringbuffer_data_t::default()];
        let vecstart = &mut vec[0] as *mut j::jack_ringbuffer_data_t;

        unsafe { j::jack_ringbuffer_get_write_vector(self.ringbuffer_handle.0, vecstart) };

        let view1 = vec[0];
        let view2 = vec[1];

        let buf1 = view1.buf as *mut u8;
        let len1 = view1.len as usize;

        let mut buf2 = view2.buf as *mut u8;
        let len2 = view2.len as usize;

        if len2 == 0 {
            // buf2 can't be null even if length is zero, so just use buf1
            buf2 = buf1;
        }

        let view1 = unsafe { std::slice::from_raw_parts_mut(buf1, len1) };
        let view2 = unsafe { std::slice::from_raw_parts_mut(buf2, len2) };
        (view1, view2)
    }

    /// Iterator that goes over all the data available to write.
    pub fn peek_iter<'a>
        (&'a mut self)
         -> std::iter::Chain<std::slice::IterMut<'a, u8>, std::slice::IterMut<'a, u8>> {

        let (mut view1, mut view2) = self.get_vector();

        view1.iter_mut().chain(view2.iter_mut())
    }
}

impl std::io::Write for RingBufferWriter {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        Ok(self.write_buffer(buf))
    }

    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::sync::atomic::{AtomicBool, Ordering};

use game::{Position, Move};
use types::{NumPlies, Score, ScoreUnit};

// TODO put actual data here
pub struct Data;
impl Data {
    pub fn combine(self, _: Data) -> Data {
        Data
    }
}

// TODO put more parameters here
#[derive(Clone)]
pub struct Param {
    pub draw_val: ScoreUnit,
}

pub fn negamax(pos: &mut Position, depth: NumPlies, param: Param,
               is_killed: &AtomicBool) -> (Score, Option<Move>, Data) {
    if is_killed.load(Ordering::Relaxed) {
        return (Score::Value(ScoreUnit(0)), None, Data);
    }
    if depth == NumPlies(0) {
        return (pos.eval(param.draw_val), None, Data);
    }

    let ans_opt: Option<(Score, Move, Data)> = {
        let temp = pos.clone();
        let move_iter = temp.legal_iter();
        let mut ans_iter = move_iter.map( |curr_move| {
            let new_param = Param { draw_val: -param.draw_val };
            let (score, _next_best_move, data) = pos.with_move(&curr_move, move |new_pos| {
                negamax(new_pos, NumPlies(depth.0 - 1), new_param, is_killed)
            });
            (score.increment(), curr_move, data)
        });

        ans_iter.next().map(move |first_ans|
            ans_iter.fold(first_ans, |prev_ans, curr_ans| {

                let (prev_score, prev_move, prev_data) = prev_ans;
                let (curr_score, curr_move, curr_data) = curr_ans;

                let combined_data = prev_data.combine(curr_data);

                if curr_score > prev_score {
                    (curr_score, curr_move, combined_data)
                } else {
                    (prev_score, prev_move, combined_data)
                }
            }
        ))
    };

    match ans_opt {
        Some((ans_score, ans_move, ans_data)) => (ans_score, Some(ans_move), ans_data),
        None => return (pos.eval(param.draw_val), None, Data),
    }
}
<commit_msg>Change negamax into imperative code<commit_after>use std::sync::atomic::{AtomicBool, Ordering};

use game::{Position, Move};
use types::{NumPlies, Score, ScoreUnit};

// TODO put actual data here
pub struct Data;
impl Data {
    pub fn combine(self, _: Data) -> Data {
        Data
    }
}

// TODO put more parameters here
#[derive(Clone)]
pub struct Param {
    pub draw_val: ScoreUnit,
}

pub fn negamax(pos: &mut Position, depth: NumPlies, param: Param,
               is_killed: &AtomicBool) -> (Score, Option<Move>, Data) {
    if is_killed.load(Ordering::Relaxed) {
        return (Score::Value(ScoreUnit(0)), None, Data);
    }
    if depth == NumPlies(0) {
        return (pos.eval(param.draw_val), None, Data);
    }

    let ans_opt: Option<(Score, Move, Data)> = {
        let temp = pos.clone();
        let move_iter = temp.legal_iter();

        let mut prev_ans_opt: Option<(Score, Move, Data)> = None;

        for curr_move in move_iter {
            let new_param = Param { draw_val: -param.draw_val };
            let (temp_score, _next_best_move, curr_data) = pos.with_move(&curr_move, move |new_pos| {
                negamax(new_pos, NumPlies(depth.0 - 1), new_param, is_killed)
            });
            let curr_score = temp_score.increment();

            let new_ans = match prev_ans_opt {
                None => (curr_score, curr_move, curr_data),
                Some(prev_ans) => {

                    let (prev_score, prev_move, prev_data) = prev_ans;

                    let combined_data = prev_data.combine(curr_data);

                    if curr_score > prev_score {
                        (curr_score, curr_move, combined_data)
                    } else {
                        (prev_score, prev_move, combined_data)
                    }
                },
            };
            prev_ans_opt = Some(new_ans);
        }

        prev_ans_opt
    };

    match ans_opt {
        Some((ans_score, ans_move, ans_data)) => (ans_score, Some(ans_move), ans_data),
        None => return (pos.eval(param.draw_val), None, Data),
    }
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::process::Command;
use std::env;

fn main() {
    let target = env::var("TARGET").unwrap();
    // let out_dir = env::var("OUT_DIR").unwrap();
    let current_dir = env::current_dir().unwrap();

    // println!("target:      {:?}", target);
    // println!("out_dir:     {:?}", out_dir);
    // println!("current_dir: {:?}", current_dir);

    let libqmlbind_dir = current_dir.join("libqmlbind");
    let libqmlbind_build_dir = libqmlbind_dir.join("build");

    // Initialize git submodule
    if !libqmlbind_dir.join(".git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    Command::new("qmake").current_dir(&libqmlbind_dir).output().unwrap();
    Command::new("make").current_dir(&libqmlbind_dir).output().unwrap();
    Command::new("make").arg("staticlib").current_dir(&libqmlbind_build_dir).output().unwrap();

    println!("cargo:rustc-link-search={}", libqmlbind_build_dir.to_str().unwrap());
    println!("cargo:rustc-link-lib=static=qmlbind");

    let qt_dir = env::var("QT_DIR").map(|p| PathBuf::from(p)).unwrap_or({
        println!("Environnement variable 'QT_DIR' not set!");
        println!("Defaulting to ${{HOME}}/Qt/${{QT_VER}}/${{QT_COMP}} where:");
        let home_dir = env::home_dir().map(|p| PathBuf::from(p)).unwrap();
        let default_qt_ver = "5.7".to_string();
        let default_qt_comp = if target.contains("linux") {
            "gcc_64".to_string()
        } else if target.contains("darwin") {
            "clang_64".to_string()
        } else {
            panic!("Unsuported platform in gallery's build.rs!")
        };
        println!("    QT_VER:  {}", default_qt_ver);
        println!("    QT_COMP: {}", default_qt_comp);
        let qt_dir_default = home_dir.join("Qt")
                                  .join(env::var("QT_VER").unwrap_or(default_qt_ver))
                                  .join(env::var("QT_COMP").unwrap_or(default_qt_comp));
        qt_dir_default
    });
    println!("Using Qt directory: {:?}", qt_dir);
    println!("Use QT_DIR environment variable to ovewrite.");

    let qt_lib_dir = qt_dir.join("lib").to_str().unwrap().to_string();

    let osx_framework = if target.contains("darwin") { "=framework" }
                        else  { "" };
    // On Linux, libraries are name "Qt5Core", not "QtCore" as on OSX
    let linux_qt_lib_ver = if target.contains("linux") { "5" }
                           else  { "" };

    println!("cargo:rustc-link-search{}={}", osx_framework, qt_lib_dir);

    println!("cargo:rustc-link-lib{}=Qt{}Core", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Network", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Gui", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Qml", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Widgets", osx_framework, linux_qt_lib_ver);

    // On Linux, Qt needs icui18n, icuuc and icudata
    if target.contains("linux") {
        println!("cargo:rustc-link-lib=icui18n");
        println!("cargo:rustc-link-lib=icuuc");
        println!("cargo:rustc-link-lib=icudata");
    }

    println!("cargo:rustc-flags=-l stdc++");
}
<commit_msg>libqmlbind-sys: Fix build script by creating 'build' directory and running commands from it<commit_after>use std::path::PathBuf;
use std::process::Command;
use std::env;

fn main() {
    let target = env::var("TARGET").unwrap();
    // let out_dir = env::var("OUT_DIR").unwrap();
    let current_dir = env::current_dir().unwrap();

    // println!("target:      {:?}", target);
    // println!("out_dir:     {:?}", out_dir);
    // println!("current_dir: {:?}", current_dir);

    let libqmlbind_dir = current_dir.join("libqmlbind");
    let libqmlbind_build_dir = libqmlbind_dir.join("build");

    std::fs::create_dir_all(&libqmlbind_build_dir).unwrap();

    // Initialize git submodule
    if !libqmlbind_dir.join(".git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    Command::new("qmake").arg("../qmlbind").current_dir(&libqmlbind_build_dir).output().unwrap();
    Command::new("make").current_dir(&libqmlbind_build_dir).output().unwrap();
    Command::new("make").arg("staticlib").current_dir(&libqmlbind_build_dir).output().unwrap();

    println!("cargo:rustc-link-search={}", libqmlbind_build_dir.to_str().unwrap());
    println!("cargo:rustc-link-lib=static=qmlbind");

    let qt_dir = env::var("QT_DIR").map(|p| PathBuf::from(p)).unwrap_or({
        println!("Environnement variable 'QT_DIR' not set!");
        println!("Defaulting to ${{HOME}}/Qt/${{QT_VER}}/${{QT_COMP}} where:");
        let home_dir = env::home_dir().map(|p| PathBuf::from(p)).unwrap();
        let default_qt_ver = "5.7".to_string();
        let default_qt_comp = if target.contains("linux") {
            "gcc_64".to_string()
        } else if target.contains("darwin") {
            "clang_64".to_string()
        } else {
            panic!("Unsuported platform in gallery's build.rs!")
        };
        println!("    QT_VER:  {}", default_qt_ver);
        println!("    QT_COMP: {}", default_qt_comp);
        let qt_dir_default = home_dir.join("Qt")
                                  .join(env::var("QT_VER").unwrap_or(default_qt_ver))
                                  .join(env::var("QT_COMP").unwrap_or(default_qt_comp));
        qt_dir_default
    });
    println!("Using Qt directory: {:?}", qt_dir);
    println!("Use QT_DIR environment variable to ovewrite.");

    let qt_lib_dir = qt_dir.join("lib").to_str().unwrap().to_string();

    let osx_framework = if target.contains("darwin") { "=framework" }
                        else  { "" };
    // On Linux, libraries are name "Qt5Core", not "QtCore" as on OSX
    let linux_qt_lib_ver = if target.contains("linux") { "5" }
                           else  { "" };

    println!("cargo:rustc-link-search{}={}", osx_framework, qt_lib_dir);

    println!("cargo:rustc-link-lib{}=Qt{}Core", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Network", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Gui", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Qml", osx_framework, linux_qt_lib_ver);
    println!("cargo:rustc-link-lib{}=Qt{}Widgets", osx_framework, linux_qt_lib_ver);

    // On Linux, Qt needs icui18n, icuuc and icudata
    if target.contains("linux") {
        println!("cargo:rustc-link-lib=icui18n");
        println!("cargo:rustc-link-lib=icuuc");
        println!("cargo:rustc-link-lib=icudata");
    }

    println!("cargo:rustc-flags=-l stdc++");
}
<|endoftext|>


<commit_before>use std::net::{Shutdown, SocketAddr};
use std::rc::Rc;
use std::{io, ptr, time};

use bytes::{Buf, BufMut, BytesMut};
use futures::{Async, Future, Poll};
use tokio_io::{AsyncRead, AsyncWrite};

use super::settings::WorkerSettings;
use super::{h1, h2, ConnectionTag, HttpHandler, IoStream};

const HTTP2_PREFACE: [u8; 14] = *b"PRI * HTTP/2.0";

enum HttpProtocol<T: IoStream, H: HttpHandler + 'static> {
    H1(h1::Http1<T, H>),
    H2(h2::Http2<T, H>),
    Unknown(Rc<WorkerSettings<H>>, Option<SocketAddr>, T, BytesMut),
}

enum ProtocolKind {
    Http1,
    Http2,
}

#[doc(hidden)]
pub struct HttpChannel<T, H>
where
    T: IoStream,
    H: HttpHandler + 'static,
{
    proto: Option<HttpProtocol<T, H>>,
    node: Option<Node<HttpChannel<T, H>>>,
    _tag: ConnectionTag,
}

impl<T, H> HttpChannel<T, H>
where
    T: IoStream,
    H: HttpHandler + 'static,
{
    pub(crate) fn new(
        settings: Rc<WorkerSettings<H>>, io: T, peer: Option<SocketAddr>,
    ) -> HttpChannel<T, H> {
        let _tag = settings.connection();

        HttpChannel {
            _tag,
            node: None,
            proto: Some(HttpProtocol::Unknown(
                settings,
                peer,
                io,
                BytesMut::with_capacity(8192),
            )),
        }
    }

    fn shutdown(&mut self) {
        match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let io = h1.io();
                let _ = IoStream::set_linger(io, Some(time::Duration::new(0, 0)));
                let _ = IoStream::shutdown(io, Shutdown::Both);
            }
            Some(HttpProtocol::H2(ref mut h2)) => h2.shutdown(),
            _ => (),
        }
    }
}

impl<T, H> Future for HttpChannel<T, H>
where
    T: IoStream,
    H: HttpHandler + 'static,
{
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if self.node.is_some() {
            let el = self as *mut _;
            self.node = Some(Node::new(el));
            let _ = match self.proto {
                Some(HttpProtocol::H1(ref mut h1)) => {
                    self.node.as_mut().map(|n| h1.settings().head().insert(n))
                }
                Some(HttpProtocol::H2(ref mut h2)) => {
                    self.node.as_mut().map(|n| h2.settings().head().insert(n))
                }
                Some(HttpProtocol::Unknown(ref mut settings, _, _, _)) => {
                    self.node.as_mut().map(|n| settings.head().insert(n))
                }
                None => unreachable!(),
            };
        }

        let mut is_eof = false;
        let kind = match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let result = h1.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        if let Some(n) = self.node.as_mut() {
                            n.remove()
                        };
                    }
                    _ => (),
                }
                return result;
            }
            Some(HttpProtocol::H2(ref mut h2)) => {
                let result = h2.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        if let Some(n) = self.node.as_mut() {
                            n.remove()
                        };
                    }
                    _ => (),
                }
                return result;
            }
            Some(HttpProtocol::Unknown(_, _, ref mut io, ref mut buf)) => {
                let mut disconnect = false;
                match io.read_available(buf) {
                    Ok(Async::Ready((read_some, stream_closed))) => {
                        is_eof = stream_closed;
                        // Only disconnect if no data was read.
                        if is_eof && !read_some {
                            disconnect = true;
                        }
                    }
                    Err(_) => {
                        disconnect = true;
                    }
                    _ => (),
                }
                if disconnect {
                    debug!("Ignored premature client disconnection");
                    if let Some(n) = self.node.as_mut() {
                        n.remove()
                    };
                    return Err(());
                }

                if buf.len() >= 14 {
                    if buf[..14] == HTTP2_PREFACE[..] {
                        ProtocolKind::Http2
                    } else {
                        ProtocolKind::Http1
                    }
                } else {
                    return Ok(Async::NotReady);
                }
            }
            None => unreachable!(),
        };

        // upgrade to specific http protocol
        if let Some(HttpProtocol::Unknown(settings, addr, io, buf)) = self.proto.take() {
            match kind {
                ProtocolKind::Http1 => {
                    self.proto = Some(HttpProtocol::H1(h1::Http1::new(
                        settings, io, addr, buf, is_eof,
                    )));
                    return self.poll();
                }
                ProtocolKind::Http2 => {
                    self.proto = Some(HttpProtocol::H2(h2::Http2::new(
                        settings,
                        io,
                        addr,
                        buf.freeze(),
                    )));
                    return self.poll();
                }
            }
        }
        unreachable!()
    }
}

pub(crate) struct Node<T> {
    next: Option<*mut Node<T>>,
    prev: Option<*mut Node<T>>,
    element: *mut T,
}

impl<T> Node<T> {
    fn new(el: *mut T) -> Self {
        Node {
            next: None,
            prev: None,
            element: el,
        }
    }

    fn insert<I>(&mut self, next: &mut Node<I>) {
        unsafe {
            let next: *mut Node<T> = next as *const _ as *mut _;

            if let Some(ref mut next2) = self.next {
                let n = next2.as_mut().unwrap();
                n.prev = Some(next);
            }
            self.next = Some(next);

            let next: &mut Node<T> = &mut *next;
            next.prev = Some(self as *mut _);
        }
    }

    fn remove(&mut self) {
        unsafe {
            self.element = ptr::null_mut();
            let next = self.next.take();
            let mut prev = self.prev.take();

            if let Some(ref mut prev) = prev {
                prev.as_mut().unwrap().next = next;
            }
        }
    }
}

impl Node<()> {
    pub(crate) fn head() -> Self {
        Node {
            next: None,
            prev: None,
            element: ptr::null_mut(),
        }
    }

    pub(crate) fn traverse<T, H>(&self)
    where
        T: IoStream,
        H: HttpHandler + 'static,
    {
        let mut next = self.next.as_ref();
        loop {
            if let Some(n) = next {
                unsafe {
                    let n: &Node<()> = &*(n.as_ref().unwrap() as *const _);
                    next = n.next.as_ref();

                    if !n.element.is_null() {
                        let ch: &mut HttpChannel<T, H> =
                            &mut *(&mut *(n.element as *mut _) as *mut () as *mut _);
                        ch.shutdown();
                    }
                }
            } else {
                return;
            }
        }
    }
}

/// Wrapper for `AsyncRead + AsyncWrite` types
pub(crate) struct WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    io: T,
}

impl<T> WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    pub fn new(io: T) -> Self {
        WrapperStream { io }
    }
}

impl<T> IoStream for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn shutdown(&mut self, _: Shutdown) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_nodelay(&mut self, _: bool) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_linger(&mut self, _: Option<time::Duration>) -> io::Result<()> {
        Ok(())
    }
}

impl<T> io::Read for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.io.read(buf)
    }
}

impl<T> io::Write for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.write(buf)
    }
    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.io.flush()
    }
}

impl<T> AsyncRead for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.read_buf(buf)
    }
}

impl<T> AsyncWrite for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        self.io.shutdown()
    }
    #[inline]
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.write_buf(buf)
    }
}
<commit_msg>Fix bug with HttpChannel linked list.<commit_after>use std::net::{Shutdown, SocketAddr};
use std::rc::Rc;
use std::{io, ptr, time};

use bytes::{Buf, BufMut, BytesMut};
use futures::{Async, Future, Poll};
use tokio_io::{AsyncRead, AsyncWrite};

use super::settings::WorkerSettings;
use super::{h1, h2, ConnectionTag, HttpHandler, IoStream};

const HTTP2_PREFACE: [u8; 14] = *b"PRI * HTTP/2.0";

enum HttpProtocol<T: IoStream, H: HttpHandler + 'static> {
    H1(h1::Http1<T, H>),
    H2(h2::Http2<T, H>),
    Unknown(Rc<WorkerSettings<H>>, Option<SocketAddr>, T, BytesMut),
}

enum ProtocolKind {
    Http1,
    Http2,
}

#[doc(hidden)]
pub struct HttpChannel<T, H>
where
    T: IoStream,
    H: HttpHandler + 'static,
{
    proto: Option<HttpProtocol<T, H>>,
    node: Option<Node<HttpChannel<T, H>>>,
    _tag: ConnectionTag,
}

impl<T, H> HttpChannel<T, H>
where
    T: IoStream,
    H: HttpHandler + 'static,
{
    pub(crate) fn new(
        settings: Rc<WorkerSettings<H>>, io: T, peer: Option<SocketAddr>,
    ) -> HttpChannel<T, H> {
        let _tag = settings.connection();

        HttpChannel {
            _tag,
            node: None,
            proto: Some(HttpProtocol::Unknown(
                settings,
                peer,
                io,
                BytesMut::with_capacity(8192),
            )),
        }
    }

    fn shutdown(&mut self) {
        match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let io = h1.io();
                let _ = IoStream::set_linger(io, Some(time::Duration::new(0, 0)));
                let _ = IoStream::shutdown(io, Shutdown::Both);
            }
            Some(HttpProtocol::H2(ref mut h2)) => h2.shutdown(),
            _ => (),
        }
    }
}

impl<T, H> Future for HttpChannel<T, H>
where
    T: IoStream,
    H: HttpHandler + 'static,
{
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if self.node.is_none() {
            let el = self as *mut _;
            self.node = Some(Node::new(el));
            let _ = match self.proto {
                Some(HttpProtocol::H1(ref mut h1)) => {
                    self.node.as_mut().map(|n| h1.settings().head().insert(n))
                }
                Some(HttpProtocol::H2(ref mut h2)) => {
                    self.node.as_mut().map(|n| h2.settings().head().insert(n))
                }
                Some(HttpProtocol::Unknown(ref mut settings, _, _, _)) => {
                    self.node.as_mut().map(|n| settings.head().insert(n))
                }
                None => unreachable!(),
            };
        }

        let mut is_eof = false;
        let kind = match self.proto {
            Some(HttpProtocol::H1(ref mut h1)) => {
                let result = h1.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        if let Some(n) = self.node.as_mut() {
                            n.remove()
                        };
                    }
                    _ => (),
                }
                return result;
            }
            Some(HttpProtocol::H2(ref mut h2)) => {
                let result = h2.poll();
                match result {
                    Ok(Async::Ready(())) | Err(_) => {
                        if let Some(n) = self.node.as_mut() {
                            n.remove()
                        };
                    }
                    _ => (),
                }
                return result;
            }
            Some(HttpProtocol::Unknown(_, _, ref mut io, ref mut buf)) => {
                let mut disconnect = false;
                match io.read_available(buf) {
                    Ok(Async::Ready((read_some, stream_closed))) => {
                        is_eof = stream_closed;
                        // Only disconnect if no data was read.
                        if is_eof && !read_some {
                            disconnect = true;
                        }
                    }
                    Err(_) => {
                        disconnect = true;
                    }
                    _ => (),
                }
                if disconnect {
                    debug!("Ignored premature client disconnection");
                    if let Some(n) = self.node.as_mut() {
                        n.remove()
                    };
                    return Err(());
                }

                if buf.len() >= 14 {
                    if buf[..14] == HTTP2_PREFACE[..] {
                        ProtocolKind::Http2
                    } else {
                        ProtocolKind::Http1
                    }
                } else {
                    return Ok(Async::NotReady);
                }
            }
            None => unreachable!(),
        };

        // upgrade to specific http protocol
        if let Some(HttpProtocol::Unknown(settings, addr, io, buf)) = self.proto.take() {
            match kind {
                ProtocolKind::Http1 => {
                    self.proto = Some(HttpProtocol::H1(h1::Http1::new(
                        settings, io, addr, buf, is_eof,
                    )));
                    return self.poll();
                }
                ProtocolKind::Http2 => {
                    self.proto = Some(HttpProtocol::H2(h2::Http2::new(
                        settings,
                        io,
                        addr,
                        buf.freeze(),
                    )));
                    return self.poll();
                }
            }
        }
        unreachable!()
    }
}

pub(crate) struct Node<T> {
    next: Option<*mut Node<T>>,
    prev: Option<*mut Node<T>>,
    element: *mut T,
}

impl<T> Node<T> {
    fn new(el: *mut T) -> Self {
        Node {
            next: None,
            prev: None,
            element: el,
        }
    }

    fn insert<I>(&mut self, next: &mut Node<I>) {
        unsafe {
            let next: *mut Node<T> = next as *const _ as *mut _;

            if let Some(ref mut next2) = self.next {
                let n = next2.as_mut().unwrap();
                n.prev = Some(next);
            }
            self.next = Some(next);

            let next: &mut Node<T> = &mut *next;
            next.prev = Some(self as *mut _);
        }
    }

    fn remove(&mut self) {
        unsafe {
            self.element = ptr::null_mut();
            let next = self.next.take();
            let mut prev = self.prev.take();

            if let Some(ref mut prev) = prev {
                prev.as_mut().unwrap().next = next;
            }
        }
    }
}

impl Node<()> {
    pub(crate) fn head() -> Self {
        Node {
            next: None,
            prev: None,
            element: ptr::null_mut(),
        }
    }

    pub(crate) fn traverse<T, H>(&self)
    where
        T: IoStream,
        H: HttpHandler + 'static,
    {
        let mut next = self.next.as_ref();
        loop {
            if let Some(n) = next {
                unsafe {
                    let n: &Node<()> = &*(n.as_ref().unwrap() as *const _);
                    next = n.next.as_ref();

                    if !n.element.is_null() {
                        let ch: &mut HttpChannel<T, H> =
                            &mut *(&mut *(n.element as *mut _) as *mut () as *mut _);
                        ch.shutdown();
                    }
                }
            } else {
                return;
            }
        }
    }
}

/// Wrapper for `AsyncRead + AsyncWrite` types
pub(crate) struct WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    io: T,
}

impl<T> WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    pub fn new(io: T) -> Self {
        WrapperStream { io }
    }
}

impl<T> IoStream for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn shutdown(&mut self, _: Shutdown) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_nodelay(&mut self, _: bool) -> io::Result<()> {
        Ok(())
    }
    #[inline]
    fn set_linger(&mut self, _: Option<time::Duration>) -> io::Result<()> {
        Ok(())
    }
}

impl<T> io::Read for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.io.read(buf)
    }
}

impl<T> io::Write for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.io.write(buf)
    }
    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.io.flush()
    }
}

impl<T> AsyncRead for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.read_buf(buf)
    }
}

impl<T> AsyncWrite for WrapperStream<T>
where
    T: AsyncRead + AsyncWrite + 'static,
{
    #[inline]
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        self.io.shutdown()
    }
    #[inline]
    fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> {
        self.io.write_buf(buf)
    }
}
<|endoftext|>


<commit_before>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct Subframe {
  /// Data containing one of the four different types of subframes.
  pub data: Data,
  /// Number of wasted bits within each sample.
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  /// A single value that represents a constant subframe.
  Constant(i32),
  /// An uncompressed subframe.
  Verbatim(Vec<i32>),
  /// Fixed linear prediction subframe.
  Fixed(Fixed),
  /// FIR linear prediction subframe.
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// Polynomial order.
  pub order: u8,
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i32; MAX_FIXED_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// FIR order.
  pub order: u8,
  /// Quantized FIR filter coefficient precision in bits.
  pub qlp_coeff_precision: u8,
  /// Quantized linear predictor coefficient shift needed in bits.
  pub quantization_level: i8,
  /// FIR filter coefficients.
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i32; MAX_LPC_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i32>,
}

/// Header for the entropy coding method.
#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  /// The type of coding method being used.
  pub method_type: CodingMethod,
  /// Data for each entropy coding method partition.
  pub data: PartitionedRice,
}

/// The available entropy coding methods.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  /// Coding partition with a 4-bit Rice parameter.
  PartitionedRice,
  /// Coding partition with a 5-bit Rice parameter.
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  /// Partition order.
  pub order: u32,
  /// Rice parameters and/or raw bits.
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  /// Size of `parameters` and `raw_bits` within the data buffer.
  pub capacity: usize,
  /// Data buffer containing both `parameters` and `raw_bits`.
  pub data: Vec<u32>,
}

impl PartitionedRiceContents {
  pub fn new(capacity: usize) -> PartitionedRiceContents {
    let full_capacity = capacity * 2;
    let mut data      = Vec::with_capacity(full_capacity);

    unsafe { data.set_len(full_capacity) }

    PartitionedRiceContents {
      capacity: capacity,
      data: data,
    }
  }

  /// Rice parameters for each context.
  #[inline]
  pub fn parameters(&mut self) -> &mut [u32] {
    &mut self.data[0..self.capacity]
  }

  /// Widths for escaped-coded partitions.
  #[inline]
  pub fn raw_bits(&mut self) -> &mut [u32] {
    &mut self.data[self.capacity..]
  }
}
<commit_msg>Finally change the subframe types<commit_after>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct Subframe {
  /// Data containing one of the four different types of subframes.
  pub data: Data,
  /// Number of wasted bits within each sample.
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  /// A single value that represents a constant subframe.
  Constant(i64),
  /// An uncompressed subframe.
  Verbatim(Vec<i64>),
  /// Fixed linear prediction subframe.
  Fixed(Fixed),
  /// FIR linear prediction subframe.
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// Polynomial order.
  pub order: u8,
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i64; MAX_FIXED_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i64>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// FIR order.
  pub order: u8,
  /// Quantized FIR filter coefficient precision in bits.
  pub qlp_coeff_precision: u8,
  /// Quantized linear predictor coefficient shift needed in bits.
  pub quantization_level: i8,
  /// FIR filter coefficients.
  pub qlp_coefficients: [i64; MAX_LPC_ORDER],
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i64; MAX_LPC_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i64>,
}

/// Header for the entropy coding method.
#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  /// The type of coding method being used.
  pub method_type: CodingMethod,
  /// Data for each entropy coding method partition.
  pub data: PartitionedRice,
}

/// The available entropy coding methods.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  /// Coding partition with a 4-bit Rice parameter.
  PartitionedRice,
  /// Coding partition with a 5-bit Rice parameter.
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  /// Partition order.
  pub order: u32,
  /// Rice parameters and/or raw bits.
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  /// Size of `parameters` and `raw_bits` within the data buffer.
  pub capacity: usize,
  /// Data buffer containing both `parameters` and `raw_bits`.
  pub data: Vec<u32>,
}

impl PartitionedRiceContents {
  pub fn new(capacity: usize) -> PartitionedRiceContents {
    let full_capacity = capacity * 2;
    let mut data      = Vec::with_capacity(full_capacity);

    unsafe { data.set_len(full_capacity) }

    PartitionedRiceContents {
      capacity: capacity,
      data: data,
    }
  }

  /// Rice parameters for each context.
  #[inline]
  pub fn parameters(&mut self) -> &mut [u32] {
    &mut self.data[0..self.capacity]
  }

  /// Widths for escaped-coded partitions.
  #[inline]
  pub fn raw_bits(&mut self) -> &mut [u32] {
    &mut self.data[self.capacity..]
  }
}
<|endoftext|>


<commit_before>use XY;
use vec::Vec2;
use view::{SizeConstraint, View, ViewWrapper};

/// Wrapper around another view, with a controlled size.
///
/// Each axis can independently be set to:
///
/// * Keep a **fixed** size
/// * Use **all** available size
/// * Use **at most** a given size
/// * Use **at least** a given size
/// * Let the wrapped view decide.
///
/// # Examples
///
/// ```
/// # use cursive::views::{BoxView,TextView};
/// // Creates a 20x4 BoxView with a TextView content.
/// let view = BoxView::with_fixed_size((20,4), TextView::new("Hello!"));
/// ```
pub struct BoxView<T: View> {
    /// Constraint on each axis
    size: XY<SizeConstraint>,

    /// `true` if the view can be squished.
    ///
    /// This means if the required size is less than the computed size,
    /// consider returning a smaller size.
    /// For instance, try to return the child's desires size.
    squishable: bool,

    /// The actual view we're wrapping.
    view: T,
}

impl<T: View> BoxView<T> {
    /// Creates a new `BoxView` with the given width and height requirements.
    ///
    /// `None` values will use the wrapped view's preferences.
    pub fn new(
        width: SizeConstraint, height: SizeConstraint, view: T
    ) -> Self {
        BoxView {
            size: (width, height).into(),
            squishable: false,
            view: view,
        }
    }

    /// Sets `self` to be squishable.
    ///
    /// A squishable `BoxView` will take a smaller size than it should when
    /// the available space is too small. In that case, it will allow the
    /// child view to contract, if it can.
    ///
    /// More specifically, if the available space is less than the size we
    /// would normally ask for, return the child size.
    pub fn squishable(mut self) -> Self {
        self.squishable = true;
        self
    }

    /// Wraps `view` in a new `BoxView` with the given size.
    pub fn with_fixed_size<S: Into<Vec2>>(size: S, view: T) -> Self {
        let size = size.into();

        BoxView::new(
            SizeConstraint::Fixed(size.x),
            SizeConstraint::Fixed(size.y),
            view,
        )
    }

    /// Wraps `view` in a new `BoxView` with fixed width.
    pub fn with_fixed_width(width: usize, view: T) -> Self {
        BoxView::new(SizeConstraint::Fixed(width), SizeConstraint::Free, view)
    }

    /// Wraps `view` in a new `BoxView` with fixed height.
    pub fn with_fixed_height(height: usize, view: T) -> Self {
        BoxView::new(SizeConstraint::Free, SizeConstraint::Fixed(height), view)
    }

    /// Wraps `view` in a `BoxView` which will take all available space.
    pub fn with_full_screen(view: T) -> Self {
        BoxView::new(SizeConstraint::Full, SizeConstraint::Full, view)
    }

    /// Wraps `view` in a `BoxView` which will take all available width.
    pub fn with_full_width(view: T) -> Self {
        BoxView::new(SizeConstraint::Full, SizeConstraint::Free, view)
    }

    /// Wraps `view` in a `BoxView` which will take all available height.
    pub fn with_full_height(view: T) -> Self {
        BoxView::new(SizeConstraint::Free, SizeConstraint::Full, view)
    }

    /// Wraps `view` in a `BoxView` which will never be bigger than `size`.
    pub fn with_max_size<S: Into<Vec2>>(size: S, view: T) -> Self {
        let size = size.into();

        BoxView::new(
            SizeConstraint::AtMost(size.x),
            SizeConstraint::AtMost(size.y),
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a maximum width.
    ///
    /// The resulting width will never be more than `max_width`.
    pub fn with_max_width(max_width: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::AtMost(max_width),
            SizeConstraint::Free,
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a maximum height.
    ///
    /// The resulting height will never be more than `max_height`.
    pub fn with_max_height(max_height: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::Free,
            SizeConstraint::AtMost(max_height),
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will never be smaller than `size`.
    pub fn with_min_size<S: Into<Vec2>>(size: S, view: T) -> Self {
        let size = size.into();

        BoxView::new(
            SizeConstraint::AtLeast(size.x),
            SizeConstraint::AtLeast(size.y),
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a minimum width.
    ///
    /// The resulting width will never be less than `min_width`.
    pub fn with_min_width(min_width: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::AtLeast(min_width),
            SizeConstraint::Free,
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a minimum height.
    ///
    /// The resulting height will never be less than `min_height`.
    pub fn with_min_height(min_height: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::Free,
            SizeConstraint::AtLeast(min_height),
            view,
        )
    }

    inner_getters!(self.view: T);
}

impl<T: View> ViewWrapper for BoxView<T> {
    wrap_impl!(self.view: T);

    fn wrap_required_size(&mut self, req: Vec2) -> Vec2 {
        let req = self.size.zip_map(req, SizeConstraint::available);
        let child_size = self.view.required_size(req);

        let result = self.size
            .zip_map(child_size.zip(req), SizeConstraint::result);

        debug!("{:?}", result);

        if self.squishable {
            // We respect the request if we're less or equal.
            let respect_req = result.zip_map(req, |res, req| res <= req);
            result.zip_map(
                respect_req.zip(child_size),
                |res, (respect, child)| {
                    if respect {
                        // If we respect the request, keep the result
                        res
                    } else {
                        // Otherwise, take the child as squish attempt.
                        child
                    }
                },
            )
        } else {
            result
        }
    }
}

#[cfg(test)]
mod tests {

    use vec::Vec2;
    use view::{Boxable, View};
    use views::DummyView;

    // No need to test `draw()` method as it's directly forwarded.

    #[test]
    fn min_size() {
        let mut min_w = DummyView.full_screen().min_width(5);

        assert_eq!(Vec2::new(5, 1), min_w.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(5, 10), min_w.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 1), min_w.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), min_w.required_size(Vec2::new(10, 10)));

        let mut min_h = DummyView.full_screen().min_height(5);

        assert_eq!(Vec2::new(1, 5), min_h.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 10), min_h.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 5), min_h.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), min_h.required_size(Vec2::new(10, 10)));

        let mut min_s = DummyView.full_screen().min_size((5, 5));

        assert_eq!(Vec2::new(5, 5), min_s.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(5, 10), min_s.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 5), min_s.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), min_s.required_size(Vec2::new(10, 10)));
    }

    #[test]
    fn max_size() {
        let mut max_w = DummyView.full_screen().max_width(5);

        assert_eq!(Vec2::new(1, 1), max_w.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 10), max_w.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(5, 1), max_w.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(5, 10), max_w.required_size(Vec2::new(10, 10)));

        let mut max_h = DummyView.full_screen().max_height(5);

        assert_eq!(Vec2::new(1, 1), max_h.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 5), max_h.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 1), max_h.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 5), max_h.required_size(Vec2::new(10, 10)));

        let mut max_s = DummyView.full_screen().max_size((5, 5));

        assert_eq!(Vec2::new(1, 1), max_s.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 5), max_s.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(5, 1), max_s.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(5, 5), max_s.required_size(Vec2::new(10, 10)));
    }

    #[test]
    fn full_screen() {
        let mut full = DummyView.full_screen();

        assert_eq!(Vec2::new(1, 1), full.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 10), full.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 1), full.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), full.required_size(Vec2::new(10, 10)));
    }

    #[test]
    fn test_get_inner() {
        use views::TextView;

        let parent = TextView::new("abc").full_screen();
        let child = parent.get_inner();
        assert_eq!(child.get_content().source(), "abc");
    }
    #[test]
    fn test_get_inner_mut() {
        use views::TextView;

        let mut parent = TextView::new("").full_screen();
        let new_value = "new";
        let child = parent.get_inner_mut();

        child.set_content(new_value);

        assert_eq!(child.get_content().source(), new_value);
    }
}
<commit_msg>Add BoxView::set_size<commit_after>use XY;
use vec::Vec2;
use view::{SizeConstraint, View, ViewWrapper};

/// Wrapper around another view, with a controlled size.
///
/// Each axis can independently be set to:
///
/// * Keep a **fixed** size
/// * Use **all** available size
/// * Use **at most** a given size
/// * Use **at least** a given size
/// * Let the wrapped view decide.
///
/// # Examples
///
/// ```
/// # use cursive::views::{BoxView,TextView};
/// // Creates a 20x4 BoxView with a TextView content.
/// let view = BoxView::with_fixed_size((20,4), TextView::new("Hello!"));
/// ```
pub struct BoxView<T: View> {
    /// Constraint on each axis
    size: XY<SizeConstraint>,

    /// `true` if the view can be squished.
    ///
    /// This means if the required size is less than the computed size,
    /// consider returning a smaller size.
    /// For instance, try to return the child's desires size.
    squishable: bool,

    /// The actual view we're wrapping.
    view: T,
}

impl<T: View> BoxView<T> {
    /// Creates a new `BoxView` with the given width and height requirements.
    ///
    /// `None` values will use the wrapped view's preferences.
    pub fn new(
        width: SizeConstraint, height: SizeConstraint, view: T
    ) -> Self {
        BoxView {
            size: (width, height).into(),
            squishable: false,
            view: view,
        }
    }

    /// Sets the size constraints for this view.
    pub fn set_constraints(&mut self, width: SizeConstraint, height: SizeConstraint) {
        self.set_width(width);
        self.set_height(height);
    }

    /// Sets the width constraint for this view.
    ///
    /// Leaves the height unchanged.
    pub fn set_width(&mut self, width: SizeConstraint) {
        self.size.x = width;
    }

    /// Sets the height constraint for this view.
    ///
    /// Leaves the width unchanged.
    pub fn set_height(&mut self, height: SizeConstraint) {
        self.size.y = height;
    }

    /// Sets `self` to be squishable.
    ///
    /// A squishable `BoxView` will take a smaller size than it should when
    /// the available space is too small. In that case, it will allow the
    /// child view to contract, if it can.
    ///
    /// More specifically, if the available space is less than the size we
    /// would normally ask for, return the child size.
    pub fn squishable(mut self) -> Self {
        self.squishable = true;
        self
    }

    /// Wraps `view` in a new `BoxView` with the given size.
    pub fn with_fixed_size<S: Into<Vec2>>(size: S, view: T) -> Self {
        let size = size.into();

        BoxView::new(
            SizeConstraint::Fixed(size.x),
            SizeConstraint::Fixed(size.y),
            view,
        )
    }

    /// Wraps `view` in a new `BoxView` with fixed width.
    pub fn with_fixed_width(width: usize, view: T) -> Self {
        BoxView::new(SizeConstraint::Fixed(width), SizeConstraint::Free, view)
    }

    /// Wraps `view` in a new `BoxView` with fixed height.
    pub fn with_fixed_height(height: usize, view: T) -> Self {
        BoxView::new(SizeConstraint::Free, SizeConstraint::Fixed(height), view)
    }

    /// Wraps `view` in a `BoxView` which will take all available space.
    pub fn with_full_screen(view: T) -> Self {
        BoxView::new(SizeConstraint::Full, SizeConstraint::Full, view)
    }

    /// Wraps `view` in a `BoxView` which will take all available width.
    pub fn with_full_width(view: T) -> Self {
        BoxView::new(SizeConstraint::Full, SizeConstraint::Free, view)
    }

    /// Wraps `view` in a `BoxView` which will take all available height.
    pub fn with_full_height(view: T) -> Self {
        BoxView::new(SizeConstraint::Free, SizeConstraint::Full, view)
    }

    /// Wraps `view` in a `BoxView` which will never be bigger than `size`.
    pub fn with_max_size<S: Into<Vec2>>(size: S, view: T) -> Self {
        let size = size.into();

        BoxView::new(
            SizeConstraint::AtMost(size.x),
            SizeConstraint::AtMost(size.y),
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a maximum width.
    ///
    /// The resulting width will never be more than `max_width`.
    pub fn with_max_width(max_width: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::AtMost(max_width),
            SizeConstraint::Free,
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a maximum height.
    ///
    /// The resulting height will never be more than `max_height`.
    pub fn with_max_height(max_height: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::Free,
            SizeConstraint::AtMost(max_height),
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will never be smaller than `size`.
    pub fn with_min_size<S: Into<Vec2>>(size: S, view: T) -> Self {
        let size = size.into();

        BoxView::new(
            SizeConstraint::AtLeast(size.x),
            SizeConstraint::AtLeast(size.y),
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a minimum width.
    ///
    /// The resulting width will never be less than `min_width`.
    pub fn with_min_width(min_width: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::AtLeast(min_width),
            SizeConstraint::Free,
            view,
        )
    }

    /// Wraps `view` in a `BoxView` which will enforce a minimum height.
    ///
    /// The resulting height will never be less than `min_height`.
    pub fn with_min_height(min_height: usize, view: T) -> Self {
        BoxView::new(
            SizeConstraint::Free,
            SizeConstraint::AtLeast(min_height),
            view,
        )
    }

    inner_getters!(self.view: T);
}

impl<T: View> ViewWrapper for BoxView<T> {
    wrap_impl!(self.view: T);

    fn wrap_required_size(&mut self, req: Vec2) -> Vec2 {
        let req = self.size.zip_map(req, SizeConstraint::available);
        let child_size = self.view.required_size(req);

        let result = self.size
            .zip_map(child_size.zip(req), SizeConstraint::result);

        debug!("{:?}", result);

        if self.squishable {
            // We respect the request if we're less or equal.
            let respect_req = result.zip_map(req, |res, req| res <= req);
            result.zip_map(
                respect_req.zip(child_size),
                |res, (respect, child)| {
                    if respect {
                        // If we respect the request, keep the result
                        res
                    } else {
                        // Otherwise, take the child as squish attempt.
                        child
                    }
                },
            )
        } else {
            result
        }
    }
}

#[cfg(test)]
mod tests {

    use vec::Vec2;
    use view::{Boxable, View};
    use views::DummyView;

    // No need to test `draw()` method as it's directly forwarded.

    #[test]
    fn min_size() {
        let mut min_w = DummyView.full_screen().min_width(5);

        assert_eq!(Vec2::new(5, 1), min_w.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(5, 10), min_w.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 1), min_w.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), min_w.required_size(Vec2::new(10, 10)));

        let mut min_h = DummyView.full_screen().min_height(5);

        assert_eq!(Vec2::new(1, 5), min_h.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 10), min_h.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 5), min_h.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), min_h.required_size(Vec2::new(10, 10)));

        let mut min_s = DummyView.full_screen().min_size((5, 5));

        assert_eq!(Vec2::new(5, 5), min_s.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(5, 10), min_s.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 5), min_s.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), min_s.required_size(Vec2::new(10, 10)));
    }

    #[test]
    fn max_size() {
        let mut max_w = DummyView.full_screen().max_width(5);

        assert_eq!(Vec2::new(1, 1), max_w.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 10), max_w.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(5, 1), max_w.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(5, 10), max_w.required_size(Vec2::new(10, 10)));

        let mut max_h = DummyView.full_screen().max_height(5);

        assert_eq!(Vec2::new(1, 1), max_h.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 5), max_h.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 1), max_h.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 5), max_h.required_size(Vec2::new(10, 10)));

        let mut max_s = DummyView.full_screen().max_size((5, 5));

        assert_eq!(Vec2::new(1, 1), max_s.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 5), max_s.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(5, 1), max_s.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(5, 5), max_s.required_size(Vec2::new(10, 10)));
    }

    #[test]
    fn full_screen() {
        let mut full = DummyView.full_screen();

        assert_eq!(Vec2::new(1, 1), full.required_size(Vec2::new(1, 1)));
        assert_eq!(Vec2::new(1, 10), full.required_size(Vec2::new(1, 10)));
        assert_eq!(Vec2::new(10, 1), full.required_size(Vec2::new(10, 1)));
        assert_eq!(Vec2::new(10, 10), full.required_size(Vec2::new(10, 10)));
    }

    #[test]
    fn test_get_inner() {
        use views::TextView;

        let parent = TextView::new("abc").full_screen();
        let child = parent.get_inner();
        assert_eq!(child.get_content().source(), "abc");
    }
    #[test]
    fn test_get_inner_mut() {
        use views::TextView;

        let mut parent = TextView::new("").full_screen();
        let new_value = "new";
        let child = parent.get_inner_mut();

        child.set_content(new_value);

        assert_eq!(child.get_content().source(), new_value);
    }
}
<|endoftext|>