<commit_before> use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') | (Normal, ' ') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<commit_msg>Add more aliases<commit_after> use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') | (Normal, ' ') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') | (Normal, 'H') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') | (Normal, 'L') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```ignore
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

use std::fs;
use std::io;
use std::path::{PathBuf, Path};

use core::Package;
use util::hex::short_hash;

pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
}

pub struct LayoutProxy<'a> {
    root: &'a Layout,
    primary: bool,
}

impl Layout {
    pub fn new(pkg: &Package, triple: Option<&str>, dest: &str) -> Layout {
        let mut path = pkg.absolute_target_dir();
        match triple {
            Some(s) => path.push(s),
            None => {}
        }
        path.push(dest);
        Layout::at(path)
    }

    pub fn at(root: PathBuf) -> Layout {
        Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root: root,
        }
    }

    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            try!(fs::create_dir_all(&self.root));
        }

        try!(mkdir(&self.deps));
        try!(mkdir(&self.native));
        try!(mkdir(&self.fingerprint));
        try!(mkdir(&self.examples));
        try!(mkdir(&self.build));

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                try!(fs::create_dir(dir));
            }
            Ok(())
        }
    }

    pub fn dest<'a>(&'a self) -> &'a Path { &self.root }
    pub fn deps<'a>(&'a self) -> &'a Path { &self.deps }
    pub fn examples<'a>(&'a self) -> &'a Path { &self.examples }

    pub fn fingerprint(&self, package: &Package) -> PathBuf {
        self.fingerprint.join(&self.pkg_dir(package))
    }

    pub fn build(&self, package: &Package) -> PathBuf {
        self.build.join(&self.pkg_dir(package))
    }

    pub fn build_out(&self, package: &Package) -> PathBuf {
        self.build(package).join("out")
    }

    fn pkg_dir(&self, pkg: &Package) -> String {
        format!("{}-{}", pkg.name(), short_hash(pkg.package_id()))
    }
}

impl<'a> LayoutProxy<'a> {
    pub fn new(root: &'a Layout, primary: bool) -> LayoutProxy<'a> {
        LayoutProxy {
            root: root,
            primary: primary,
        }
    }

    pub fn root(&self) -> &'a Path {
        if self.primary {self.root.dest()} else {self.root.deps()}
    }
    pub fn deps(&self) -> &'a Path { self.root.deps() }

    pub fn examples(&self) -> &'a Path { self.root.examples() }

    pub fn build(&self, pkg: &Package) -> PathBuf { self.root.build(pkg) }

    pub fn build_out(&self, pkg: &Package) -> PathBuf { self.root.build_out(pkg) }

    pub fn proxy(&self) -> &'a Layout { self.root }
}
<commit_msg>Auto merge of #1396 - alexcrichton:issue-1390, r=huonw<commit_after>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```ignore
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

use std::fs;
use std::io;
use std::path::{PathBuf, Path};

use core::Package;
use util::hex::short_hash;

pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
}

pub struct LayoutProxy<'a> {
    root: &'a Layout,
    primary: bool,
}

impl Layout {
    pub fn new(pkg: &Package, triple: Option<&str>, dest: &str) -> Layout {
        let mut path = pkg.absolute_target_dir();
        // Flexible target specifications often point at filenames, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name.
        if let Some(triple) = triple {
            path.push(Path::new(triple).file_stem().unwrap());
        }
        path.push(dest);
        Layout::at(path)
    }

    pub fn at(root: PathBuf) -> Layout {
        Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root: root,
        }
    }

    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            try!(fs::create_dir_all(&self.root));
        }

        try!(mkdir(&self.deps));
        try!(mkdir(&self.native));
        try!(mkdir(&self.fingerprint));
        try!(mkdir(&self.examples));
        try!(mkdir(&self.build));

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                try!(fs::create_dir(dir));
            }
            Ok(())
        }
    }

    pub fn dest<'a>(&'a self) -> &'a Path { &self.root }
    pub fn deps<'a>(&'a self) -> &'a Path { &self.deps }
    pub fn examples<'a>(&'a self) -> &'a Path { &self.examples }

    pub fn fingerprint(&self, package: &Package) -> PathBuf {
        self.fingerprint.join(&self.pkg_dir(package))
    }

    pub fn build(&self, package: &Package) -> PathBuf {
        self.build.join(&self.pkg_dir(package))
    }

    pub fn build_out(&self, package: &Package) -> PathBuf {
        self.build(package).join("out")
    }

    fn pkg_dir(&self, pkg: &Package) -> String {
        format!("{}-{}", pkg.name(), short_hash(pkg.package_id()))
    }
}

impl<'a> LayoutProxy<'a> {
    pub fn new(root: &'a Layout, primary: bool) -> LayoutProxy<'a> {
        LayoutProxy {
            root: root,
            primary: primary,
        }
    }

    pub fn root(&self) -> &'a Path {
        if self.primary {self.root.dest()} else {self.root.deps()}
    }
    pub fn deps(&self) -> &'a Path { self.root.deps() }

    pub fn examples(&self) -> &'a Path { self.root.examples() }

    pub fn build(&self, pkg: &Package) -> PathBuf { self.root.build(pkg) }

    pub fn build_out(&self, pkg: &Package) -> PathBuf { self.root.build_out(pkg) }

    pub fn proxy(&self) -> &'a Layout { self.root }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use buffer::Buffered;
use stream::*;
use demuxer::demux::*;
use error::*;

use std::io::BufRead;

#[derive(Clone,Debug,PartialEq)]
pub struct GlobalInfo {
    pub duration: Option<u64>,
    pub streams: Vec<Stream>,
//    programs: Vec<StreamGroup>,
//    chapters: Vec<StreamGroup>,
}

pub struct DemuxerContext<'a> {
    demuxer: Box<Demuxer+'a>,
    reader: Box<Buffered>,
    info: GlobalInfo,
}

impl<'a> DemuxerContext<'a> {
    pub fn new<R: Buffered+'static>(demuxer: Box<Demuxer + 'a>, reader: Box<R>) -> Self {
        DemuxerContext {
            demuxer:  demuxer,
            reader:   reader,
            info: GlobalInfo {
                duration: None,
                streams:  Vec::with_capacity(2),
            }
        }
    }

    pub fn read_headers(&mut self) -> Result<()> {
        let ref mut demux = self.demuxer;

        let res = demux.read_headers(&self.reader, &mut self.info);
        match res {
            Err(e)   => Err(e),
            Ok(seek) => {
                //TODO: handle seeking here
                let res = self.reader.seek(seek);
                try!(self.reader.fill_buf());
                println!("stream now at index: {:?}", res);
                Ok(())
            }
        }
    }

    pub fn read_packet(&mut self) -> Result<Event> {
        let ref mut demux = self.demuxer;

        let res = demux.read_packet(&self.reader);
        match res {
            Err(e)   => Err(e),
            Ok((seek, event)) => {
                //TODO: handle seeking here
                let res = self.reader.seek(seek);
                try!(self.reader.fill_buf());
                if let &Event::NewStream(ref st) = &event {
                    self.info.streams.push(st.clone());
                }
                println!("stream now at index: {:?}", res);
                Ok(event)
            }
        }
    }
}

<commit_msg>demux: Make GlobalInfo public<commit_after>#![allow(dead_code)]

use buffer::Buffered;
use stream::*;
use demuxer::demux::*;
use error::*;

use std::io::BufRead;

#[derive(Clone,Debug,PartialEq)]
pub struct GlobalInfo {
    pub duration: Option<u64>,
    pub streams: Vec<Stream>,
//    programs: Vec<StreamGroup>,
//    chapters: Vec<StreamGroup>,
}

pub struct DemuxerContext<'a> {
    demuxer: Box<Demuxer+'a>,
    reader: Box<Buffered>,
    pub info: GlobalInfo,
}

impl<'a> DemuxerContext<'a> {
    pub fn new<R: Buffered+'static>(demuxer: Box<Demuxer + 'a>, reader: Box<R>) -> Self {
        DemuxerContext {
            demuxer:  demuxer,
            reader:   reader,
            info: GlobalInfo {
                duration: None,
                streams:  Vec::with_capacity(2),
            }
        }
    }

    pub fn read_headers(&mut self) -> Result<()> {
        let ref mut demux = self.demuxer;

        let res = demux.read_headers(&self.reader, &mut self.info);
        match res {
            Err(e)   => Err(e),
            Ok(seek) => {
                //TODO: handle seeking here
                let res = self.reader.seek(seek);
                try!(self.reader.fill_buf());
                println!("stream now at index: {:?}", res);
                Ok(())
            }
        }
    }

    pub fn read_packet(&mut self) -> Result<Event> {
        let ref mut demux = self.demuxer;

        let res = demux.read_packet(&self.reader);
        match res {
            Err(e)   => Err(e),
            Ok((seek, event)) => {
                //TODO: handle seeking here
                let res = self.reader.seek(seek);
                try!(self.reader.fill_buf());
                if let &Event::NewStream(ref st) = &event {
                    self.info.streams.push(st.clone());
                }
                println!("stream now at index: {:?}", res);
                Ok(event)
            }
        }
    }
}

<|endoftext|>


<commit_before>extern crate proc_macro;

use quote::{quote, ToTokens};
use synstructure::{decl_derive, Structure};

fn discriminant_attr(v: &synstructure::VariantInfo) -> Option<syn::Lit> {
    v.ast().attrs.iter().find_map(|attr| match attr {
        syn::Attribute {
            style: syn::AttrStyle::Outer,
            path,
            ..
        } if path.is_ident("wasmbin") => {
            let args = attr
                .parse_args::<syn::MetaNameValue>()
                .expect("Wrong format of wasmbin attr");
            assert!(args.path.is_ident("discriminant"));
            Some(args.lit)
        }
        _ => None,
    })
}

fn wasmbin_derive(s: Structure) -> proc_macro2::TokenStream {
    let (encode_discriminant, decode) = match s.ast().data {
        syn::Data::Enum(_) => {
            if !s.ast().attrs.iter().any(|attr| {
                attr.path.is_ident("repr")
                    && attr
                        .parse_args::<syn::Ident>()
                        .map_or(false, |ident| ident == "u8")
            }) {
                panic!("Wasmbin enums must use #[repr(u8)].");
            }

            let mut decoders = quote!();
            let mut decode_other = quote!({ return Ok(None) });

            let encode_discriminant = s.each_variant(|v| {
                v.ast()
                    .discriminant
                    .as_ref()
                    .map(|(_, discriminant)| quote!(#discriminant))
                    .or_else(|| discriminant_attr(v).map(|lit| quote!(#lit)))
                    .map_or_else(
                        || {
                            let fields = v.ast().fields;
                            assert_eq!(fields.len(), 1, "Single field is required for catch-all discriminants.");
                            let field = fields.iter().next().unwrap();
                            let construct = match &field.ident {
                                Some(ident) => quote!({ #ident: res }),
                                None => quote!((res))
                            };
                            let variant_name = v.ast().ident;
                            decode_other = quote! {
                                if let Some(res) = WasmbinDecodeWithDiscriminant::maybe_decode_with_discriminant(discriminant, r)? {
                                    Self::#variant_name #construct
                                } else #decode_other
                            };
                            quote!(Ok(()))
                        },
                        |discriminant| {
                            let construct = v.construct(|_, _| quote!(WasmbinDecode::decode(r)?));
                            (quote!(#discriminant => #construct,)).to_tokens(&mut decoders);
                            quote!(<u8 as WasmbinEncode>::encode(&#discriminant, w))
                        },
                    )
            });

            (
                quote! {
                    match *self {
                        #encode_discriminant
                    }?;
                },
                quote! {
                    gen impl WasmbinDecodeWithDiscriminant for @Self {
                        fn maybe_decode_with_discriminant(discriminant: u8, r: &mut impl std::io::Read) -> Result<Option<Self>, DecodeError> {
                            Ok(Some(match discriminant {
                                #decoders
                                _ => #decode_other
                            }))
                        }
                    }

                    gen impl WasmbinDecode for @Self {
                        fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
                            WasmbinDecodeWithDiscriminant::decode(r)
                        }
                    }
                },
            )
        }
        _ => {
            let variants = s.variants();
            assert_eq!(variants.len(), 1);
            let v = &variants[0];
            let construct = v.construct(|_, _| quote!(WasmbinDecode::decode(r)?));
            match discriminant_attr(v) {
                Some(discriminant) => (
                    quote! {
                        <u8 as WasmbinEncode>::encode(&#discriminant, w)?;
                    },
                    quote! {
                        gen impl WasmbinDecodeWithDiscriminant for @Self {
                            fn maybe_decode_with_discriminant(discriminant: u8, r: &mut impl std::io::Read) -> Result<Option<Self>, DecodeError> {
                                Ok(match discriminant {
                                    #discriminant => Some(#construct),
                                    _ => None
                                })
                            }
                        }

                        gen impl WasmbinDecode for @Self {
                            fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
                                WasmbinDecodeWithDiscriminant::decode(r)
                            }
                        }
                    },
                ),
                None => (
                    quote! {},
                    quote! {
                        gen impl WasmbinDecode for @Self {
                            fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
                                Ok(#construct)
                            }
                        }
                    },
                ),
            }
        }
    };

    let encode_body = s.each(|bi| {
        quote! {
            WasmbinEncode::encode(#bi, w)?
        }
    });

    s.gen_impl(quote! {
        use crate::{WasmbinEncode, WasmbinDecode, WasmbinDecodeWithDiscriminant, DecodeError};

        gen impl WasmbinEncode for @Self {
            fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
                #encode_discriminant
                match *self { #encode_body }
                Ok(())
            }
        }

        #decode
    })
}

fn wasmbin_countable_derive(s: Structure) -> proc_macro2::TokenStream {
    s.gen_impl(quote! {
        gen impl crate::WasmbinCountable for @Self {}
    })
}

#[proc_macro_attribute]
pub fn wasmbin_discriminants(
    _attr: proc_macro::TokenStream,
    input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let mut input: syn::DeriveInput = syn::parse(input).unwrap();
    let e = match &mut input.data {
        syn::Data::Enum(e) => e,
        _ => panic!("This attribute can only be used on enums"),
    };
    let mut seen_non_units = false;
    for v in &mut e.variants {
        match v.fields {
            syn::Fields::Unit => {}
            _ => seen_non_units = true,
        }
        #[cfg(not(feature = "nightly"))]
        {
            if let Some((_, discriminant)) = v.discriminant.take() {
                v.attrs
                    .push(syn::parse_quote!(#[wasmbin(discriminant = #discriminant)]));
            }
        }
    }
    assert!(
        seen_non_units,
        "Attribute shouldn't be used on C-like enums"
    );
    input.into_token_stream().into()
}

decl_derive!([Wasmbin, attributes(wasmbin)] => wasmbin_derive);
decl_derive!([WasmbinCountable] => wasmbin_countable_derive);
<commit_msg>Make derive a bit more readable<commit_after>extern crate proc_macro;

use quote::{quote, ToTokens};
use std::borrow::Cow;
use synstructure::{decl_derive, Structure, VariantInfo};

fn discriminant_attr(v: &VariantInfo) -> Option<syn::Expr> {
    v.ast().attrs.iter().find_map(|attr| match attr {
        syn::Attribute {
            style: syn::AttrStyle::Outer,
            path,
            ..
        } if path.is_ident("wasmbin") => {
            syn::custom_keyword!(discriminant);

            Some(
                attr.parse_args_with(|parser: syn::parse::ParseStream| {
                    parser.parse::<discriminant>()?;
                    parser.parse::<syn::Token![=]>()?;
                    parser.parse()
                })
                .unwrap(),
            )
        }
        _ => None,
    })
}

fn gen_encode_discriminant(discriminant: &syn::Expr) -> proc_macro2::TokenStream {
    quote!(<u8 as WasmbinEncode>::encode(&#discriminant, w)?)
}

fn gen_decode(v: &VariantInfo) -> proc_macro2::TokenStream {
    v.construct(|_, _| quote!(WasmbinDecode::decode(r)?))
}

fn wasmbin_derive(s: Structure) -> proc_macro2::TokenStream {
    let (encode_discriminant, decode) = match s.ast().data {
        syn::Data::Enum(_) => {
            if !s.ast().attrs.iter().any(|attr| {
                attr.path.is_ident("repr")
                    && attr
                        .parse_args::<syn::Ident>()
                        .map_or(false, |ident| ident == "u8")
            }) {
                panic!("Wasmbin enums must use #[repr(u8)].");
            }

            let mut encode_discriminant = quote!();

            let mut decoders = quote!();
            let mut decode_other = quote!({ return Ok(None) });

            for v in s.variants() {
                let discriminant = v
                    .ast()
                    .discriminant
                    .as_ref()
                    .map(|(_, discriminant)| Cow::Borrowed(discriminant))
                    .or_else(|| discriminant_attr(v).map(Cow::Owned));

                match discriminant {
                    Some(discriminant) => {
                        let pat = v.pat();

                        let encode = gen_encode_discriminant(&discriminant);
                        (quote!(#pat => #encode,)).to_tokens(&mut encode_discriminant);

                        let construct = gen_decode(v);
                        (quote!(#discriminant => #construct,)).to_tokens(&mut decoders);
                    }
                    None => {
                        let fields = v.ast().fields;
                        assert_eq!(
                            fields.len(),
                            1,
                            "Single field is required for catch-all discriminants."
                        );
                        let field = fields.iter().next().unwrap();
                        let construct = match &field.ident {
                            Some(ident) => quote!({ #ident: res }),
                            None => quote!((res)),
                        };
                        let variant_name = v.ast().ident;
                        decode_other = quote! {
                            if let Some(res) = WasmbinDecodeWithDiscriminant::maybe_decode_with_discriminant(discriminant, r)? {
                                Self::#variant_name #construct
                            } else #decode_other
                        };
                    }
                }
            }

            (
                quote! {
                    match *self {
                        #encode_discriminant
                        _ => {}
                    }
                },
                quote! {
                    gen impl WasmbinDecodeWithDiscriminant for @Self {
                        fn maybe_decode_with_discriminant(discriminant: u8, r: &mut impl std::io::Read) -> Result<Option<Self>, DecodeError> {
                            Ok(Some(match discriminant {
                                #decoders
                                _ => #decode_other
                            }))
                        }
                    }

                    gen impl WasmbinDecode for @Self {
                        fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
                            WasmbinDecodeWithDiscriminant::decode(r)
                        }
                    }
                },
            )
        }
        _ => {
            let variants = s.variants();
            assert_eq!(variants.len(), 1);
            let v = &variants[0];
            let decode = gen_decode(v);
            match discriminant_attr(v) {
                Some(discriminant) => (
                    gen_encode_discriminant(&discriminant),
                    quote! {
                        gen impl WasmbinDecodeWithDiscriminant for @Self {
                            fn maybe_decode_with_discriminant(discriminant: u8, r: &mut impl std::io::Read) -> Result<Option<Self>, DecodeError> {
                                Ok(match discriminant {
                                    #discriminant => Some(#decode),
                                    _ => None
                                })
                            }
                        }

                        gen impl WasmbinDecode for @Self {
                            fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
                                WasmbinDecodeWithDiscriminant::decode(r)
                            }
                        }
                    },
                ),
                None => (
                    quote! {},
                    quote! {
                        gen impl WasmbinDecode for @Self {
                            fn decode(r: &mut impl std::io::Read) -> Result<Self, DecodeError> {
                                Ok(#decode)
                            }
                        }
                    },
                ),
            }
        }
    };

    let encode_body = s.each(|bi| {
        quote! {
            WasmbinEncode::encode(#bi, w)?
        }
    });

    s.gen_impl(quote! {
        use crate::{WasmbinEncode, WasmbinDecode, WasmbinDecodeWithDiscriminant, DecodeError};

        gen impl WasmbinEncode for @Self {
            fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
                #encode_discriminant;
                match *self { #encode_body }
                Ok(())
            }
        }

        #decode
    })
}

fn wasmbin_countable_derive(s: Structure) -> proc_macro2::TokenStream {
    s.gen_impl(quote! {
        gen impl crate::WasmbinCountable for @Self {}
    })
}

#[proc_macro_attribute]
pub fn wasmbin_discriminants(
    _attr: proc_macro::TokenStream,
    input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let mut input: syn::DeriveInput = syn::parse(input).unwrap();
    let e = match &mut input.data {
        syn::Data::Enum(e) => e,
        _ => panic!("This attribute can only be used on enums"),
    };
    let mut seen_non_units = false;
    for v in &mut e.variants {
        match v.fields {
            syn::Fields::Unit => {}
            _ => seen_non_units = true,
        }
        #[cfg(not(feature = "nightly"))]
        {
            if let Some((_, discriminant)) = v.discriminant.take() {
                v.attrs
                    .push(syn::parse_quote!(#[wasmbin(discriminant = #discriminant)]));
            }
        }
    }
    assert!(
        seen_non_units,
        "Attribute shouldn't be used on C-like enums"
    );
    input.into_token_stream().into()
}

decl_derive!([Wasmbin, attributes(wasmbin)] => wasmbin_derive);
decl_derive!([WasmbinCountable] => wasmbin_countable_derive);
<|endoftext|>


<commit_before>use crate::{
    analysis::{rust_type::RustType, trampoline_parameters::Transformation},
    env::Env,
    library,
    nameutil::is_gstring,
    traits::*,
};

pub trait TrampolineFromGlib {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String;
}

impl TrampolineFromGlib for Transformation {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String {
        use crate::analysis::conversion_type::ConversionType::*;
        let need_type_name = need_downcast || is_need_type_name(env, self.typ);
        match self.conversion_type {
            Direct => self.name.clone(),
            Scalar | Option | Result { .. } => format!("from_glib({})", self.name),
            Borrow | Pointer => {
                let is_borrow = self.conversion_type == Borrow;
                let need_type_name = need_type_name || (is_borrow && nullable);
                let (mut left, mut right) = from_glib_xxx(self.transfer, is_borrow);
                let type_name = RustType::try_new(env, self.typ).into_string();
                if need_type_name {
                    if is_borrow && nullable {
                        left = format!("Option::<{}>::{}", type_name, left);
                    } else {
                        left = format!("{}::{}", type_name, left);
                    }
                }

                if !nullable {
                    left = format!(
                        "{}{}",
                        if need_downcast && is_borrow { "" } else { "&" },
                        left
                    );
                } else if nullable && is_borrow {
                    if is_gstring(&type_name) {
                        right = format!("(*{}).as_ref().map(|s| s.as_str())", right);
                    } else {
                        right = format!("{}.as_ref().as_ref()", right);
                    }
                } else if is_gstring(&type_name) {
                    right = format!("{}.as_str()", right);
                } else {
                    right = format!("{}.as_ref()", right);
                }

                if need_downcast && is_borrow {
                    right = format!("{}.unsafe_cast_ref()", right);
                } else if need_downcast {
                    right = format!("{}.unsafe_cast()", right);
                }

                format!("{}{}{}", left, self.name, right)
            }
            Unknown => format!("/*Unknown conversion*/{}", self.name),
        }
    }
}

pub fn from_glib_xxx(transfer: library::Transfer, is_borrow: bool) -> (String, String) {
    use crate::library::Transfer::*;
    match transfer {
        None if is_borrow => ("from_glib_borrow(".into(), ")".into()),
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("from_glib_container(".into(), ")".into()),
    }
}

fn is_need_type_name(env: &Env, type_id: library::TypeId) -> bool {
    if type_id.ns_id == library::INTERNAL_NAMESPACE {
        use crate::library::{Fundamental::*, Type::*};
        matches!(env.type_(type_id), Fundamental(Utf8 | Filename | OsString))
    } else {
        false
    }
}
<commit_msg>trampoline_from_glib: Replace broken deref with as_ref<commit_after>use crate::{
    analysis::{rust_type::RustType, trampoline_parameters::Transformation},
    env::Env,
    library,
    nameutil::is_gstring,
    traits::*,
};

pub trait TrampolineFromGlib {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String;
}

impl TrampolineFromGlib for Transformation {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String {
        use crate::analysis::conversion_type::ConversionType::*;
        let need_type_name = need_downcast || is_need_type_name(env, self.typ);
        match self.conversion_type {
            Direct => self.name.clone(),
            Scalar | Option | Result { .. } => format!("from_glib({})", self.name),
            Borrow | Pointer => {
                let is_borrow = self.conversion_type == Borrow;
                let need_type_name = need_type_name || (is_borrow && nullable);
                let (mut left, mut right) = from_glib_xxx(self.transfer, is_borrow);
                let type_name = RustType::try_new(env, self.typ).into_string();
                if need_type_name {
                    if is_borrow && nullable {
                        left = format!("Option::<{}>::{}", type_name, left);
                    } else {
                        left = format!("{}::{}", type_name, left);
                    }
                }

                if !nullable {
                    left = format!(
                        "{}{}",
                        if need_downcast && is_borrow { "" } else { "&" },
                        left
                    );
                } else if nullable && is_borrow {
                    if is_gstring(&type_name) {
                        right = format!("{}.as_ref().as_ref().map(|s| s.as_str())", right);
                    } else {
                        right = format!("{}.as_ref().as_ref()", right);
                    }
                } else if is_gstring(&type_name) {
                    right = format!("{}.as_str()", right);
                } else {
                    right = format!("{}.as_ref()", right);
                }

                if need_downcast && is_borrow {
                    right = format!("{}.unsafe_cast_ref()", right);
                } else if need_downcast {
                    right = format!("{}.unsafe_cast()", right);
                }

                format!("{}{}{}", left, self.name, right)
            }
            Unknown => format!("/*Unknown conversion*/{}", self.name),
        }
    }
}

pub fn from_glib_xxx(transfer: library::Transfer, is_borrow: bool) -> (String, String) {
    use crate::library::Transfer::*;
    match transfer {
        None if is_borrow => ("from_glib_borrow(".into(), ")".into()),
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("from_glib_container(".into(), ")".into()),
    }
}

fn is_need_type_name(env: &Env, type_id: library::TypeId) -> bool {
    if type_id.ns_id == library::INTERNAL_NAMESPACE {
        use crate::library::{Fundamental::*, Type::*};
        matches!(env.type_(type_id), Fundamental(Utf8 | Filename | OsString))
    } else {
        false
    }
}
<|endoftext|>


<commit_before>use clap::ArgMatches;
use libp2p::gossipsub::{GossipsubConfig, GossipsubConfigBuilder};
use serde_derive::{Deserialize, Serialize};
use types::multiaddr::{Error as MultiaddrError, Multiaddr};
//use std::time::Duration;

/// The beacon node topic string to subscribe to.
pub const BEACON_PUBSUB_TOPIC: &str = "beacon_node";
pub const SHARD_TOPIC_PREFIX: &str = "attestations"; // single topic for all attestation for the moment.

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
/// Network configuration for lighthouse.
pub struct Config {
    /// IP address to listen on.
    listen_addresses: Vec<String>,
    /// Gossipsub configuration parameters.
    #[serde(skip)]
    pub gs_config: GossipsubConfig,
    /// Configuration parameters for node identification protocol.
    #[serde(skip)]
    pub identify_config: IdentifyConfig,
    /// List of nodes to initially connect to.
    boot_nodes: Vec<String>,
    /// Client version
    pub client_version: String,
    /// List of extra topics to initially subscribe to as strings.
    pub topics: Vec<String>,
}

impl Default for Config {
    /// Generate a default network configuration.
    fn default() -> Self {
        Config {
            listen_addresses: vec!["/ip4/127.0.0.1/tcp/9000".to_string()],
            gs_config: GossipsubConfigBuilder::new()
                .max_gossip_size(4_000_000)
                //                .inactivity_timeout(Duration::from_secs(90))
                .build(),
            identify_config: IdentifyConfig::default(),
            boot_nodes: vec![],
            client_version: version::version(),
            topics: Vec::new(),
        }
    }
}

/// Generates a default Config.
impl Config {
    pub fn new() -> Self {
        Config::default()
    }

    pub fn listen_addresses(&self) -> Result<Vec<Multiaddr>, MultiaddrError> {
        self.listen_addresses.iter().map(|s| s.parse()).collect()
    }

    pub fn boot_nodes(&self) -> Result<Vec<Multiaddr>, MultiaddrError> {
        self.boot_nodes.iter().map(|s| s.parse()).collect()
    }

    pub fn apply_cli_args(&mut self, args: &ArgMatches) -> Result<(), &'static str> {
        if let Some(listen_address_str) = args.value_of("listen-address") {
            let listen_addresses = listen_address_str.split(',').map(Into::into).collect();
            self.listen_addresses = listen_addresses;
        }

        if let Some(boot_addresses_str) = args.value_of("boot-nodes") {
            let boot_addresses = boot_addresses_str.split(',').map(Into::into).collect();
            self.boot_nodes = boot_addresses;
        }

        Ok(())
    }
}

/// The configuration parameters for the Identify protocol
#[derive(Debug, Clone)]
pub struct IdentifyConfig {
    /// The protocol version to listen on.
    pub version: String,
    /// The client's name and version for identification.
    pub user_agent: String,
}

impl Default for IdentifyConfig {
    fn default() -> Self {
        Self {
            version: "/eth/serenity/1.0".to_string(),
            user_agent: version::version(),
        }
    }
}

/// Creates a standard network config from a chain_id.
///
/// This creates specified network parameters for each chain type.
impl From<ChainType> for Config {
    fn from(chain_type: ChainType) -> Self {
        match chain_type {
            ChainType::Foundation => Config::default(),

            ChainType::LighthouseTestnet => {
                let boot_nodes = vec!["/ip4/127.0.0.1/tcp/9000"
                    .parse()
                    .expect("correct multiaddr")];
                Self {
                    boot_nodes,
                    ..Config::default()
                }
            }

            ChainType::Other => Config::default(),
        }
    }
}

pub enum ChainType {
    Foundation,
    LighthouseTestnet,
    Other,
}

/// Maps a chain id to a ChainType.
impl From<u8> for ChainType {
    fn from(chain_id: u8) -> Self {
        match chain_id {
            1 => ChainType::Foundation,
            2 => ChainType::LighthouseTestnet,
            _ => ChainType::Other,
        }
    }
}
<commit_msg>Add custom inactivity timeout to gossipsub<commit_after>use clap::ArgMatches;
use libp2p::gossipsub::{GossipsubConfig, GossipsubConfigBuilder};
use serde_derive::{Deserialize, Serialize};
use std::time::Duration;
use types::multiaddr::{Error as MultiaddrError, Multiaddr};

/// The beacon node topic string to subscribe to.
pub const BEACON_PUBSUB_TOPIC: &str = "beacon_node";
pub const SHARD_TOPIC_PREFIX: &str = "attestations"; // single topic for all attestation for the moment.

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
/// Network configuration for lighthouse.
pub struct Config {
    /// IP address to listen on.
    listen_addresses: Vec<String>,
    /// Gossipsub configuration parameters.
    #[serde(skip)]
    pub gs_config: GossipsubConfig,
    /// Configuration parameters for node identification protocol.
    #[serde(skip)]
    pub identify_config: IdentifyConfig,
    /// List of nodes to initially connect to.
    boot_nodes: Vec<String>,
    /// Client version
    pub client_version: String,
    /// List of extra topics to initially subscribe to as strings.
    pub topics: Vec<String>,
}

impl Default for Config {
    /// Generate a default network configuration.
    fn default() -> Self {
        Config {
            listen_addresses: vec!["/ip4/127.0.0.1/tcp/9000".to_string()],
            gs_config: GossipsubConfigBuilder::new()
                .max_gossip_size(4_000_000)
                .inactivity_timeout(Duration::from_secs(90))
                .build(),
            identify_config: IdentifyConfig::default(),
            boot_nodes: vec![],
            client_version: version::version(),
            topics: Vec::new(),
        }
    }
}

/// Generates a default Config.
impl Config {
    pub fn new() -> Self {
        Config::default()
    }

    pub fn listen_addresses(&self) -> Result<Vec<Multiaddr>, MultiaddrError> {
        self.listen_addresses.iter().map(|s| s.parse()).collect()
    }

    pub fn boot_nodes(&self) -> Result<Vec<Multiaddr>, MultiaddrError> {
        self.boot_nodes.iter().map(|s| s.parse()).collect()
    }

    pub fn apply_cli_args(&mut self, args: &ArgMatches) -> Result<(), &'static str> {
        if let Some(listen_address_str) = args.value_of("listen-address") {
            let listen_addresses = listen_address_str.split(',').map(Into::into).collect();
            self.listen_addresses = listen_addresses;
        }

        if let Some(boot_addresses_str) = args.value_of("boot-nodes") {
            let boot_addresses = boot_addresses_str.split(',').map(Into::into).collect();
            self.boot_nodes = boot_addresses;
        }

        Ok(())
    }
}

/// The configuration parameters for the Identify protocol
#[derive(Debug, Clone)]
pub struct IdentifyConfig {
    /// The protocol version to listen on.
    pub version: String,
    /// The client's name and version for identification.
    pub user_agent: String,
}

impl Default for IdentifyConfig {
    fn default() -> Self {
        Self {
            version: "/eth/serenity/1.0".to_string(),
            user_agent: version::version(),
        }
    }
}

/// Creates a standard network config from a chain_id.
///
/// This creates specified network parameters for each chain type.
impl From<ChainType> for Config {
    fn from(chain_type: ChainType) -> Self {
        match chain_type {
            ChainType::Foundation => Config::default(),

            ChainType::LighthouseTestnet => {
                let boot_nodes = vec!["/ip4/127.0.0.1/tcp/9000"
                    .parse()
                    .expect("correct multiaddr")];
                Self {
                    boot_nodes,
                    ..Config::default()
                }
            }

            ChainType::Other => Config::default(),
        }
    }
}

pub enum ChainType {
    Foundation,
    LighthouseTestnet,
    Other,
}

/// Maps a chain id to a ChainType.
impl From<u8> for ChainType {
    fn from(chain_id: u8) -> Self {
        match chain_id {
            1 => ChainType::Foundation,
            2 => ChainType::LighthouseTestnet,
            _ => ChainType::Other,
        }
    }
}
<|endoftext|>