<commit_before>//! Syntax Tree library used throughout the rust analyzer.
//!
//! Properties:
//!   - easy and fast incremental re-parsing
//!   - graceful handling of errors
//!   - full-fidelity representation (*any* text can be precisely represented as
//!     a syntax tree)
//!
//! For more information, see the [RFC]. Current implementation is inspired by
//! the [Swift] one.
//!
//! The most interesting modules here are `syntax_node` (which defines concrete
//! syntax tree) and `ast` (which defines abstract syntax tree on top of the
//! CST). The actual parser live in a separate `ra_parser` crate, thought the
//! lexer lives in this crate.
//!
//! [RFC]: <https://github.com/rust-lang/rfcs/pull/2256>
//! [Swift]: <https://github.com/apple/swift/blob/13d593df6f359d0cb2fc81cfaac273297c539455/lib/Syntax/README.md>

mod syntax_node;
mod syntax_text;
mod syntax_error;
mod parsing;
mod string_lexing;
mod validation;
mod ptr;

pub mod algo;
pub mod ast;

pub use rowan::{SmolStr, TextRange, TextUnit};
pub use ra_parser::SyntaxKind;
pub use crate::{
    ast::AstNode,
    syntax_error::{SyntaxError, SyntaxErrorKind, Location},
    syntax_text::SyntaxText,
    syntax_node::{Direction,  SyntaxNode, WalkEvent, TreeArc},
    ptr::{SyntaxNodePtr, AstPtr},
    parsing::{tokenize, Token},
};

use ra_text_edit::AtomTextEdit;
use crate::syntax_node::GreenNode;

/// `SourceFile` represents a parse tree for a single Rust file.
pub use crate::ast::SourceFile;

impl SourceFile {
    fn new(green: GreenNode, errors: Vec<SyntaxError>) -> TreeArc<SourceFile> {
        let root = SyntaxNode::new(green, errors);
        if cfg!(debug_assertions) {
            validation::validate_block_structure(&root);
        }
        assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
        TreeArc::cast(root)
    }

    pub fn parse(text: &str) -> TreeArc<SourceFile> {
        let (green, errors) = parsing::parse_text(text);
        SourceFile::new(green, errors)
    }

    pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
        self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
    }

    pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> {
        parsing::incremental_reparse(self.syntax(), edit, self.errors())
            .map(|(green_node, errors)| SourceFile::new(green_node, errors))
    }

    fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
        let text = edit.apply(self.syntax().text().to_string());
        SourceFile::parse(&text)
    }

    pub fn errors(&self) -> Vec<SyntaxError> {
        let mut errors = self.syntax.root_data().clone();
        errors.extend(validation::validate(self));
        errors
    }
}

pub fn check_fuzz_invariants(text: &str) {
    let file = SourceFile::parse(text);
    let root = file.syntax();
    validation::validate_block_structure(root);
    let _ = file.errors();
}
<commit_msg>add API guide to ra_syntax<commit_after>//! Syntax Tree library used throughout the rust analyzer.
//!
//! Properties:
//!   - easy and fast incremental re-parsing
//!   - graceful handling of errors
//!   - full-fidelity representation (*any* text can be precisely represented as
//!     a syntax tree)
//!
//! For more information, see the [RFC]. Current implementation is inspired by
//! the [Swift] one.
//!
//! The most interesting modules here are `syntax_node` (which defines concrete
//! syntax tree) and `ast` (which defines abstract syntax tree on top of the
//! CST). The actual parser live in a separate `ra_parser` crate, thought the
//! lexer lives in this crate.
//!
//! See `api_walkthrough` test in this file for a quick API tour!
//!
//! [RFC]: <https://github.com/rust-lang/rfcs/pull/2256>
//! [Swift]: <https://github.com/apple/swift/blob/13d593df6f359d0cb2fc81cfaac273297c539455/lib/Syntax/README.md>

mod syntax_node;
mod syntax_text;
mod syntax_error;
mod parsing;
mod string_lexing;
mod validation;
mod ptr;

pub mod algo;
pub mod ast;

pub use rowan::{SmolStr, TextRange, TextUnit};
pub use ra_parser::SyntaxKind;
pub use crate::{
    ast::AstNode,
    syntax_error::{SyntaxError, SyntaxErrorKind, Location},
    syntax_text::SyntaxText,
    syntax_node::{Direction,  SyntaxNode, WalkEvent, TreeArc},
    ptr::{SyntaxNodePtr, AstPtr},
    parsing::{tokenize, Token},
};

use ra_text_edit::AtomTextEdit;
use crate::syntax_node::GreenNode;

/// `SourceFile` represents a parse tree for a single Rust file.
pub use crate::ast::SourceFile;

impl SourceFile {
    fn new(green: GreenNode, errors: Vec<SyntaxError>) -> TreeArc<SourceFile> {
        let root = SyntaxNode::new(green, errors);
        if cfg!(debug_assertions) {
            validation::validate_block_structure(&root);
        }
        assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
        TreeArc::cast(root)
    }

    pub fn parse(text: &str) -> TreeArc<SourceFile> {
        let (green, errors) = parsing::parse_text(text);
        SourceFile::new(green, errors)
    }

    pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
        self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
    }

    pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> {
        parsing::incremental_reparse(self.syntax(), edit, self.errors())
            .map(|(green_node, errors)| SourceFile::new(green_node, errors))
    }

    fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
        let text = edit.apply(self.syntax().text().to_string());
        SourceFile::parse(&text)
    }

    pub fn errors(&self) -> Vec<SyntaxError> {
        let mut errors = self.syntax.root_data().clone();
        errors.extend(validation::validate(self));
        errors
    }
}

pub fn check_fuzz_invariants(text: &str) {
    let file = SourceFile::parse(text);
    let root = file.syntax();
    validation::validate_block_structure(root);
    let _ = file.errors();
}

/// This test does not assert anything and instead just shows off the crate's
/// API.
#[test]
fn api_walkthrough() {
    use ast::{ModuleItemOwner, NameOwner};

    let source_code = "
        fn foo() {
            1 + 1
        }
    ";
    // `SourceFile` is the main entry point.
    //
    // Note how `parse` does not return a `Result`: even completely invalid
    // source code might be parsed.
    let file = SourceFile::parse(source_code);

    // Due to the way ownership is set up, owned syntax Nodes always live behind
    // a `TreeArc` smart pointer. `TreeArc` is roughly an `std::sync::Arc` which
    // points to the whole file instead of an individual node.
    let file: TreeArc<SourceFile> = file;

    // `SourceFile` is the root of the syntax tree. We can iterate file's items:
    let mut func = None;
    for item in file.items() {
        match item.kind() {
            ast::ModuleItemKind::FnDef(f) => func = Some(f),
            _ => unreachable!(),
        }
    }
    // The returned items are always references.
    let func: &ast::FnDef = func.unwrap();

    // All nodes implement `ToOwned` trait, with `Owned = TreeArc<Self>`.
    // `to_owned` is a cheap operation: atomic increment.
    let _owned_func: TreeArc<ast::FnDef> = func.to_owned();

    // Each AST node has a bunch of getters for children. All getters return
    // `Option`s though, to account for incomplete code. Some getters are common
    // for several kinds of node. In this case, a trait like `ast::NameOwner`
    // usually exists. By convention, all ast types should be used with `ast::`
    // qualifier.
    let name: Option<&ast::Name> = func.name();
    let name = name.unwrap();
    assert_eq!(name.text(), "foo");

    // Let's get the `1 + 1` expression!
    let block: &ast::Block = func.body().unwrap();
    let expr: &ast::Expr = block.expr().unwrap();

    // "Enum"-like nodes are represented using the "kind" pattern. It allows us
    // to match exhaustively against all flavors of nodes, while maintaining
    // internal representation flexibility. The drawback is that one can't write
    // nested matches as one pattern.
    let bin_expr: &ast::BinExpr = match expr.kind() {
        ast::ExprKind::BinExpr(e) => e,
        _ => unreachable!(),
    };

    // Besides the "typed" AST API, there's an untyped CST one as well.
    // To switch from AST to CST, call `.syntax()` method:
    let expr_syntax: &SyntaxNode = expr.syntax();

    // Note how `expr` and `bin_expr` are in fact the same node underneath:
    assert!(std::ptr::eq(expr_syntax, bin_expr.syntax()));

    // To go from CST to AST, `AstNode::cast` function is used:
    let expr = match ast::Expr::cast(expr_syntax) {
        Some(e) => e,
        None => unreachable!(),
    };

    // Note how expr is also a reference!
    let expr: &ast::Expr = expr;

    // This is possible because the underlying representation is the same:
    assert_eq!(
        expr as *const ast::Expr as *const u8,
        expr_syntax as *const SyntaxNode as *const u8
    );

    // The two properties each syntax node has is a `SyntaxKind`:
    assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR);

    // And text range:
    assert_eq!(expr_syntax.range(), TextRange::from_to(32.into(), 37.into()));

    // You can get node's text as a `SyntaxText` object, which will traverse the
    // tree collecting token's text:
    let text: SyntaxText<'_> = expr_syntax.text();
    assert_eq!(text.to_string(), "1 + 1");

    // There's a bunch of traversal methods on `SyntaxNode`:
    assert_eq!(expr_syntax.parent(), Some(block.syntax()));
    assert_eq!(block.syntax().first_child().map(|it| it.kind()), Some(SyntaxKind::L_CURLY));
    assert_eq!(expr_syntax.next_sibling().map(|it| it.kind()), Some(SyntaxKind::WHITESPACE));

    // As well as some iterator helpers:
    let f = expr_syntax.ancestors().find_map(ast::FnDef::cast);
    assert_eq!(f, Some(&*func));
    assert!(expr_syntax.siblings(Direction::Next).any(|it| it.kind() == SyntaxKind::R_CURLY));
    assert_eq!(
        expr_syntax.descendants().count(),
        8, // 5 tokens `1`, ` `, `+`, ` `, `!`
           // 2 child literal expressions: `1`, `1`
           // 1 the node itself: `1 + 1`
    );

    // There's also a `preorder` method with a more fine-grained iteration control:
    let mut buf = String::new();
    let mut indent = 0;
    for event in expr_syntax.preorder() {
        match event {
            WalkEvent::Enter(node) => {
                buf += &format!(
                    "{:indent$}{:?} {:?}\n",
                    " ",
                    node.text(),
                    node.kind(),
                    indent = indent
                );
                indent += 2;
            }
            WalkEvent::Leave(_) => indent -= 2,
        }
    }
    assert_eq!(indent, 0);
    assert_eq!(
        buf.trim(),
        r#"
"1 + 1" BIN_EXPR
  "1" LITERAL
    "1" INT_NUMBER
  " " WHITESPACE
  "+" PLUS
  " " WHITESPACE
  "1" LITERAL
    "1" INT_NUMBER
"#
        .trim()
    );

    // To recursively process the tree, there are three approaches:
    // 1. explicitly call getter methods on AST nodes.
    // 2. use descendants and `AstNode::cast`.
    // 3. use descendants and the visitor.
    //
    // Here's how the first one looks like:
    let exprs_cast: Vec<String> = file
        .syntax()
        .descendants()
        .filter_map(ast::Expr::cast)
        .map(|expr| expr.syntax().text().to_string())
        .collect();

    // An alternative is to use a visitor. The visitor does not do traversal
    // automatically (so it's more akin to a generic lambda) and is constructed
    // from closures. This seems more flexible than a single generated visitor
    // trait.
    use algo::visit::{visitor, Visitor};
    let mut exprs_visit = Vec::new();
    for node in file.syntax().descendants() {
        if let Some(result) =
            visitor().visit::<ast::Expr, _>(|expr| expr.syntax().text().to_string()).accept(node)
        {
            exprs_visit.push(result);
        }
    }
    assert_eq!(exprs_cast, exprs_visit);
}
<|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

extern crate num;
extern crate test;

use std::str::FromStr;
use std::num::{FromPrimitive, ToPrimitive};

use test::Bencher;

use num::{BigInt, Integer, One, Zero};

struct Context {
    numer: BigInt,
    accum: BigInt,
    denom: BigInt,
}

impl Context {
    fn new() -> Context {
        Context {
            numer: One::one(),
            accum: Zero::zero(),
            denom: One::one(),
        }
    }

    fn from_i32(i: i32) -> BigInt {
        FromPrimitive::from_i32(i).unwrap()
    }

    fn extract_digit(&self) -> i32 {
        if self.numer > self.accum {return -1;}
        let (q, r) =
            (&self.numer * Context::from_i32(3) + &self.accum)
            .div_rem(&self.denom);
        if r + &self.numer >= self.denom {return -1;}
        q.to_i32().unwrap()
    }

    fn next_term(&mut self, k: i32) {
        let y2 = Context::from_i32(k * 2 + 1);
        self.accum = (&self.accum + (&self.numer << 1)) * &y2;
        self.numer = &self.numer * Context::from_i32(k);
        self.denom = &self.denom * y2;
    }

    fn eliminate_digit(&mut self, d: i32) {
        let d = Context::from_i32(d);
        let ten = Context::from_i32(10);
        self.accum = (&self.accum - &self.denom * d) * &ten;
        self.numer = &self.numer * ten;
    }
}

fn pidigits(n: isize) {
    let mut k = 0;
    let mut context = Context::new();

    for i in (1..(n+1)) {
        let mut d;
        loop {
            k += 1;
            context.next_term(k);
            d = context.extract_digit();
            if d != -1 {break;}
        }

        print!("{}", d);
        if i % 10 == 0 {print!("\t:{}\n", i);}

        context.eliminate_digit(d);
    }

    let m = n % 10;
    if m != 0 {
        for _ in (m..10) { print!(" "); }
        print!("\t:{}\n", n);
    }
}

static DEFAULT_DIGITS: isize = 512;

#[bench]
fn use_bencher(b: &mut Bencher) {
    b.iter(|| pidigits(DEFAULT_DIGITS))
}

fn main() {
    let args = std::os::args();
    let args = args.as_slice();
    let n = if args.len() < 2 {
        DEFAULT_DIGITS
    } else {
        FromStr::from_str(args[1].as_slice()).unwrap()
    };
    pidigits(n);
}
<commit_msg>Fix warnings in pidigits benchmark<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

#![feature(core)]
#![feature(test)]

extern crate num;
extern crate test;

use std::str::FromStr;
use std::num::{FromPrimitive, ToPrimitive};

use test::Bencher;

use num::{BigInt, Integer, One, Zero};

struct Context {
    numer: BigInt,
    accum: BigInt,
    denom: BigInt,
}

impl Context {
    fn new() -> Context {
        Context {
            numer: One::one(),
            accum: Zero::zero(),
            denom: One::one(),
        }
    }

    fn from_i32(i: i32) -> BigInt {
        FromPrimitive::from_i32(i).unwrap()
    }

    fn extract_digit(&self) -> i32 {
        if self.numer > self.accum {return -1;}
        let (q, r) =
            (&self.numer * Context::from_i32(3) + &self.accum)
            .div_rem(&self.denom);
        if r + &self.numer >= self.denom {return -1;}
        q.to_i32().unwrap()
    }

    fn next_term(&mut self, k: i32) {
        let y2 = Context::from_i32(k * 2 + 1);
        self.accum = (&self.accum + (&self.numer << 1)) * &y2;
        self.numer = &self.numer * Context::from_i32(k);
        self.denom = &self.denom * y2;
    }

    fn eliminate_digit(&mut self, d: i32) {
        let d = Context::from_i32(d);
        let ten = Context::from_i32(10);
        self.accum = (&self.accum - &self.denom * d) * &ten;
        self.numer = &self.numer * ten;
    }
}

fn pidigits(n: isize) {
    let mut k = 0;
    let mut context = Context::new();

    for i in (1..(n+1)) {
        let mut d;
        loop {
            k += 1;
            context.next_term(k);
            d = context.extract_digit();
            if d != -1 {break;}
        }

        print!("{}", d);
        if i % 10 == 0 {print!("\t:{}\n", i);}

        context.eliminate_digit(d);
    }

    let m = n % 10;
    if m != 0 {
        for _ in (m..10) { print!(" "); }
        print!("\t:{}\n", n);
    }
}

static DEFAULT_DIGITS: isize = 512;

#[bench]
fn use_bencher(b: &mut Bencher) {
    b.iter(|| pidigits(DEFAULT_DIGITS))
}

#[allow(dead_code)]
fn main() {
    let args = std::env::args().collect::<Vec<_>>();
    let n = if args.len() < 2 {
        DEFAULT_DIGITS
    } else {
        FromStr::from_str(args[1].as_slice()).unwrap()
    };
    pidigits(n);
}
<|endoftext|>


<commit_before>//
// sprocketnes/mapper.rs
//
// Copyright (c) 2013 Mozilla Foundation
// Author: Patrick Walton
//

use cpu::Mem;
use rom::Rom;

pub struct Mapper {
    rom: &Rom,

    // FIXME: ~fn is awful here; we need the function region work.
    // FIXME: We may want to trait-ify this. It's hard because of the region in Rom though. Perhaps
    // we need region-parameterized &Traits.
    loadb: ~fn(this: &Mapper, addr: u16) -> u8;
    storeb: ~fn(this: &Mapper, addr: u16, val: u8);
    loadw: ~fn(this: &Mapper, addr: u16) -> u16;
    storew: ~fn(this: &Mapper, addr: u16, val: u16);
    iface: @IMapper,    // FIXME: segfaults if I use ~IMapper, ugh
}

pub trait IMapper {
    fn loadb(&mut self, rom: &Rom, addr: u16) -> u8;
    fn storeb(&mut self, rom: &Rom, addr: u16, val: u8);
    fn loadw(&mut self, rom: &Rom, addr: u16) -> u16;
    fn storew(&mut self, rom: &Rom, addr: u16, val: u16);
}

pub impl Mapper {
    static fn new(rom: &a/Rom) -> Mapper/&a {
        let iface = match rom.header.mapper() {
            0 => @Nrom as @IMapper,
            _ => fail ~"unsupported mapper"
        };
        Mapper { rom: rom, iface: iface }
    }
}

// Forward onto the interface.
pub impl Mapper : Mem {
    fn loadb(&mut self, addr: u16) -> u8      { self.iface.loadb(self.rom, addr) }
    fn storeb(&mut self, addr: u16, val: u8)  { self.iface.storeb(self.rom, addr, val) }
    fn loadw(&mut self, addr: u16) -> u16     { self.iface.loadw(self.rom, addr) }
    fn storew(&mut self, addr: u16, val: u16) { self.iface.storew(self.rom, addr, val) }
}

//
// Mapper 0 (NROM)
//
// See http://wiki.nesdev.com/w/index.php/NROM
//

// TODO: RAM.
pub struct Nrom;

// TODO: Support 32K ROMs (NROM-256).
pub impl Nrom : IMapper {
    fn loadb(&mut self, rom: &Rom, addr: u16) -> u8 {
        if addr <= 0x8000 {
            0   // FIXME
        } else {
            rom.prg[addr & 0x3fff]
        }
    }
    fn storeb(&mut self, _: &Rom, _: u16, _: u8) {
        // TODO
    }

    fn loadw(&mut self, rom: &Rom, addr: u16) -> u16 {
        // FIXME: On x86 use unsafe code to do an unaligned read.
        self.loadb(rom, addr) as u16 | (self.loadb(rom, addr + 1) as u16 << 8)
    }

    fn storew(&mut self, _: &Rom, _: u16, _: u16) {
        // TODO
    }
}

<commit_msg>Make mapper not use the GC<commit_after>//
// sprocketnes/mapper.rs
//
// Copyright (c) 2013 Mozilla Foundation
// Author: Patrick Walton
//

use cpu::Mem;
use rom::Rom;

pub struct Mapper {
    rom: &Rom,

    // FIXME: ~fn is awful here; we need the function region work.
    // FIXME: We should trait-ify this. It's hard because of the region in Rom though. I guess we
    // need region-parameterized &Traits to fix this. Dependent on the function region work.
    // NB: This exposed a nasty Rust bug! ~IMapper segfaults; see "segfault" branch.
    loadb: ~fn(this: &mut Mapper, addr: u16) -> u8,
    storeb: ~fn(this: &mut Mapper, addr: u16, val: u8),
    loadw: ~fn(this: &mut Mapper, addr: u16) -> u16,
    storew: ~fn(this: &mut Mapper, addr: u16, val: u16),
}

trait IMapper {
    fn loadb(self, this: &mut Mapper, addr: u16) -> u8;
    fn storeb(self, this: &mut Mapper, addr: u16, val: u8);
    fn loadw(self, this: &mut Mapper, addr: u16) -> u16;
    fn storew(self, this: &mut Mapper, addr: u16, val: u16);
}

pub impl Mapper {
    static fn new(rom: &a/Rom) -> Mapper/&a {
        match rom.header.mapper() {
            0 => Mapper {
                rom: rom,

                loadb:  |this, addr|      Nrom.loadb(this, addr),
                storeb: |this, addr, val| Nrom.storeb(this, addr, val),
                loadw:  |this, addr|      Nrom.loadw(this, addr),
                storew: |this, addr, val| Nrom.storew(this, addr, val)
            },
            _ => fail ~"unsupported mapper"
        }
    }
}

// Forward onto the interface.
pub impl Mapper : Mem {
    fn loadb(&mut self, addr: u16) -> u8      { (self.loadb)(self, addr) }
    fn storeb(&mut self, addr: u16, val: u8)  { (self.storeb)(self, addr, val) }
    fn loadw(&mut self, addr: u16) -> u16     { (self.loadw)(self, addr) }
    fn storew(&mut self, addr: u16, val: u16) { (self.storew)(self, addr, val) }
}

//
// Mapper 0 (NROM)
//
// See http://wiki.nesdev.com/w/index.php/NROM
//

// TODO: RAM.
pub struct Nrom;

// TODO: Support 32K ROMs (NROM-256).
pub impl Nrom : IMapper {
    fn loadb(self, this: &mut Mapper, addr: u16) -> u8 {
        if addr <= 0x8000 {
            0   // FIXME
        } else {
            this.rom.prg[addr & 0x3fff]
        }
    }
    fn storeb(self, _: &mut Mapper, _: u16, _: u8) {
        // TODO
    }

    fn loadw(self, this: &mut Mapper, addr: u16) -> u16 {
        // FIXME: On x86 use unsafe code to do an unaligned read.
        self.loadb(this, addr) as u16 | (self.loadb(this, addr + 1) as u16 << 8)
    }

    fn storew(self, _: &mut Mapper, _: u16, _: u16) {
        // TODO
    }
}

<|endoftext|>


<commit_before>

use serde::de::Error;
use serde::{Serialize, Serializer, Deserialize, Deserializer};

use std::marker::PhantomData;

use prelude::*;

use EdgeType;
use graph::Node;
use graph::{IndexType, Edge};
use stable_graph::StableGraph;
use util::rev;
use serde_utils::MappedSequenceVisitor;
use serde_utils::CollectSeqWithLength;
use serde_utils::{IntoSerializable, FromDeserialized};

use super::super::serialization::{EdgeProperty, invalid_length_err, invalid_node_err};

// Serialization representation for StableGraph
// Keep in sync with deserialization and Graph
#[derive(Serialize)]
#[serde(rename = "Graph")]
#[serde(bound(serialize = "N: Serialize, E: Serialize, Ix: IndexType + Serialize"))]
pub struct SerStableGraph<'a, N: 'a, E: 'a, Ix: 'a + IndexType> {
    #[serde(serialize_with="ser_stable_graph_nodes")]
    nodes: &'a [Node<Option<N>, Ix>],
    #[serde(serialize_with="ser_stable_graph_node_holes")]
    node_holes: &'a [Node<Option<N>, Ix>],
    edge_property: EdgeProperty,
    #[serde(serialize_with="ser_stable_graph_edges")]
    edges: &'a [Edge<Option<E>, Ix>],
}

// Deserialization representation for StableGraph
// Keep in sync with serialization and Graph
#[derive(Deserialize)]
#[serde(rename = "Graph")]
#[serde(bound(deserialize = "N: Deserialize<'de>, E: Deserialize<'de>, Ix: IndexType + Deserialize<'de>"))]
pub struct DeserStableGraph<N, E, Ix> {
    #[serde(deserialize_with="deser_stable_graph_nodes")]
    nodes: Vec<Node<Option<N>, Ix>>,
    #[serde(default="Vec::new")]
    node_holes: Vec<NodeIndex<Ix>>,
    edge_property: EdgeProperty,
    #[serde(deserialize_with="deser_stable_graph_edges")]
    edges: Vec<Edge<Option<E>, Ix>>,
}

fn ser_stable_graph_nodes<S, N, Ix>(nodes: &&[Node<Option<N>, Ix>], serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
          N: Serialize,
          Ix: Serialize + IndexType,
{
    serializer.collect_seq_with_length(
        nodes.iter()
             .filter(|node| node.weight.is_some())
             .count(),
        nodes.iter()
             .filter_map(|node| node.weight.as_ref()))
}

fn ser_stable_graph_node_holes<S, N, Ix>(nodes: &&[Node<Option<N>, Ix>], serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
          N: Serialize,
          Ix: Serialize + IndexType,
{
    serializer.collect_seq_with_length(
        nodes.iter()
             .filter(|node| node.weight.is_none())
             .count(),
        nodes.iter()
             .enumerate()
             .filter_map(|(i, node)| if node.weight.is_none() { Some(NodeIndex::<Ix>::new(i)) } else { None }))
}

fn ser_stable_graph_edges<S, E, Ix>(edges: &&[Edge<Option<E>, Ix>], serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
          E: Serialize,
          Ix: Serialize + IndexType,
{
    serializer.collect_seq_exact(
        edges.iter()
            .map(|edge| edge.weight.as_ref().map(|w| (
               edge.source(),
               edge.target(),
               w
            ))))
}

fn deser_stable_graph_nodes<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Node<Option<N>, Ix>>, D::Error>
    where D: Deserializer<'de>,
          N: Deserialize<'de>,
          Ix: IndexType + Deserialize<'de>,
{
    deserializer.deserialize_seq(MappedSequenceVisitor::new(|n|
        Ok(Node {
            weight: Some(n),
            next: [EdgeIndex::end(); 2],
        })
    ))
}

fn deser_stable_graph_edges<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Edge<Option<N>, Ix>>, D::Error>
    where D: Deserializer<'de>,
          N: Deserialize<'de>,
          Ix: IndexType + Deserialize<'de>,
{
    deserializer.deserialize_seq(MappedSequenceVisitor::<Option<(NodeIndex<Ix>, NodeIndex<Ix>, N)>, _, _>::new(|x|
        if let Some((i, j, w)) = x {
            Ok(Edge {
                weight: Some(w),
                node: [i, j],
                next: [EdgeIndex::end(); 2],
            })
        } else {
            Ok(Edge {
                weight: None,
                node: [NodeIndex::end(); 2],
                next: [EdgeIndex::end(); 2],
            })
        }
    ))
}

impl<'a, N, E, Ty, Ix> IntoSerializable for &'a StableGraph<N, E, Ty, Ix>
    where Ix: IndexType,
          Ty: EdgeType,
{
    type Output = SerStableGraph<'a, N, E, Ix>;
    fn into_serializable(self) -> Self::Output {
        SerStableGraph {
            nodes: self.raw_nodes(),
            node_holes: self.raw_nodes(),
            edges: self.raw_edges(),
            edge_property: EdgeProperty::from(PhantomData::<Ty>),
        }
    }
}

impl<N, E, Ty, Ix> Serialize for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType + Serialize,
          N: Serialize,
          E: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        self.into_serializable().serialize(serializer)
    }
}

impl<'a, N, E, Ty, Ix> FromDeserialized for StableGraph<N, E, Ty, Ix>
    where Ix: IndexType,
          Ty: EdgeType,
{
    type Input = DeserStableGraph<N, E, Ix>;
    fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
        where E2: Error
    {
        let ty = PhantomData::<Ty>::from_deserialized(input.edge_property)?;
        let mut nodes = input.nodes;
        let node_holes = input.node_holes;
        let edges = input.edges;
        if edges.len() >= <Ix as IndexType>::max().index() {
            Err(invalid_length_err::<Ix, _>("edge", edges.len()))?
        }

        // insert Nones for each hole
        let mut offset = node_holes.len();
        let node_bound = node_holes.len() + nodes.len();
        for hole_pos in rev(node_holes) {
            offset -= 1;
            if hole_pos.index() >= node_bound {
                Err(invalid_node_err(hole_pos.index(), node_bound))?;
            }
            let insert_pos = hole_pos.index() - offset;
            nodes.insert(insert_pos, Node {
                weight: None,
                next: [EdgeIndex::end(); 2],
            });
        }

        if nodes.len() >= <Ix as IndexType>::max().index() {
            Err(invalid_length_err::<Ix, _>("node", nodes.len()))?
        }

        let node_bound = nodes.len();
        let mut sgr = StableGraph {
            g: Graph {
                nodes: nodes,
                edges: edges,
                ty: ty,
            },
            node_count: 0,
            edge_count: 0,
            free_edge: EdgeIndex::end(),
            free_node: NodeIndex::end(),
        };
        sgr.link_edges().map_err(|i| invalid_node_err(i.index(), node_bound))?;
        Ok(sgr)
    }
}

impl<'de, N, E, Ty, Ix> Deserialize<'de> for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType + Deserialize<'de>,
          N: Deserialize<'de>,
          E: Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        Self::from_deserialized(DeserStableGraph::deserialize(deserializer)?)
    }
}

#[test]
fn test_from_deserialized_with_holes() {
    use graph::node_index;
    use stable_graph::StableUnGraph;
    use serde::de::value::Error as SerdeError;
    use itertools::assert_equal;

    let input = DeserStableGraph::<_, (), u32> {
        nodes: vec![
            Node {
                weight: Some(1),
                next: [EdgeIndex::end(); 2],
            },
            Node {
                weight: Some(4),
                next: [EdgeIndex::end(); 2],
            },
            Node {
                weight: Some(5),
                next: [EdgeIndex::end(); 2],
            },
        ],
        node_holes: vec![
            node_index(0),
            node_index(2),
            node_index(3),
            node_index(6),
        ],
        edges: vec![],
        edge_property: EdgeProperty::Undirected,
    };
    let graph = StableUnGraph::from_deserialized::<SerdeError>(input).unwrap();

    assert_eq!(graph.node_count(), 3);
    assert_equal(
        graph.raw_nodes().iter().map(|n| n.weight.as_ref().cloned()),
        vec![None, Some(1), None, None, Some(4), Some(5), None]);
}

<commit_msg>FEAT: Slice to node/edge bound when serializing StableGraph<commit_after>

use serde::de::Error;
use serde::{Serialize, Serializer, Deserialize, Deserializer};

use std::marker::PhantomData;

use prelude::*;

use EdgeType;
use graph::Node;
use graph::{IndexType, Edge};
use stable_graph::StableGraph;
use util::rev;
use serde_utils::MappedSequenceVisitor;
use serde_utils::CollectSeqWithLength;
use serde_utils::{IntoSerializable, FromDeserialized};
use visit::NodeIndexable;

use super::super::serialization::{EdgeProperty, invalid_length_err, invalid_node_err};

// Serialization representation for StableGraph
// Keep in sync with deserialization and Graph
#[derive(Serialize)]
#[serde(rename = "Graph")]
#[serde(bound(serialize = "N: Serialize, E: Serialize, Ix: IndexType + Serialize"))]
pub struct SerStableGraph<'a, N: 'a, E: 'a, Ix: 'a + IndexType> {
    #[serde(serialize_with="ser_stable_graph_nodes")]
    nodes: &'a [Node<Option<N>, Ix>],
    #[serde(serialize_with="ser_stable_graph_node_holes")]
    node_holes: &'a [Node<Option<N>, Ix>],
    edge_property: EdgeProperty,
    #[serde(serialize_with="ser_stable_graph_edges")]
    edges: &'a [Edge<Option<E>, Ix>],
}

// Deserialization representation for StableGraph
// Keep in sync with serialization and Graph
#[derive(Deserialize)]
#[serde(rename = "Graph")]
#[serde(bound(deserialize = "N: Deserialize<'de>, E: Deserialize<'de>, Ix: IndexType + Deserialize<'de>"))]
pub struct DeserStableGraph<N, E, Ix> {
    #[serde(deserialize_with="deser_stable_graph_nodes")]
    nodes: Vec<Node<Option<N>, Ix>>,
    #[serde(default="Vec::new")]
    node_holes: Vec<NodeIndex<Ix>>,
    edge_property: EdgeProperty,
    #[serde(deserialize_with="deser_stable_graph_edges")]
    edges: Vec<Edge<Option<E>, Ix>>,
}

fn ser_stable_graph_nodes<S, N, Ix>(nodes: &&[Node<Option<N>, Ix>], serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
          N: Serialize,
          Ix: Serialize + IndexType,
{
    serializer.collect_seq_with_length(
        nodes.iter()
             .filter(|node| node.weight.is_some())
             .count(),
        nodes.iter()
             .filter_map(|node| node.weight.as_ref()))
}

fn ser_stable_graph_node_holes<S, N, Ix>(nodes: &&[Node<Option<N>, Ix>], serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
          N: Serialize,
          Ix: Serialize + IndexType,
{
    serializer.collect_seq_with_length(
        nodes.iter()
             .filter(|node| node.weight.is_none())
             .count(),
        nodes.iter()
             .enumerate()
             .filter_map(|(i, node)| if node.weight.is_none() { Some(NodeIndex::<Ix>::new(i)) } else { None }))
}

fn ser_stable_graph_edges<S, E, Ix>(edges: &&[Edge<Option<E>, Ix>], serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer,
          E: Serialize,
          Ix: Serialize + IndexType,
{
    serializer.collect_seq_exact(
        edges.iter()
            .map(|edge| edge.weight.as_ref().map(|w| (
               edge.source(),
               edge.target(),
               w
            ))))
}

fn deser_stable_graph_nodes<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Node<Option<N>, Ix>>, D::Error>
    where D: Deserializer<'de>,
          N: Deserialize<'de>,
          Ix: IndexType + Deserialize<'de>,
{
    deserializer.deserialize_seq(MappedSequenceVisitor::new(|n|
        Ok(Node {
            weight: Some(n),
            next: [EdgeIndex::end(); 2],
        })
    ))
}

fn deser_stable_graph_edges<'de, D, N, Ix>(deserializer: D) -> Result<Vec<Edge<Option<N>, Ix>>, D::Error>
    where D: Deserializer<'de>,
          N: Deserialize<'de>,
          Ix: IndexType + Deserialize<'de>,
{
    deserializer.deserialize_seq(MappedSequenceVisitor::<Option<(NodeIndex<Ix>, NodeIndex<Ix>, N)>, _, _>::new(|x|
        if let Some((i, j, w)) = x {
            Ok(Edge {
                weight: Some(w),
                node: [i, j],
                next: [EdgeIndex::end(); 2],
            })
        } else {
            Ok(Edge {
                weight: None,
                node: [NodeIndex::end(); 2],
                next: [EdgeIndex::end(); 2],
            })
        }
    ))
}

impl<'a, N, E, Ty, Ix> IntoSerializable for &'a StableGraph<N, E, Ty, Ix>
    where Ix: IndexType,
          Ty: EdgeType,
{
    type Output = SerStableGraph<'a, N, E, Ix>;
    fn into_serializable(self) -> Self::Output {
        let nodes = &self.raw_nodes()[..self.node_bound()];
        let edges = &self.raw_edges()[..self.edge_bound()];
        SerStableGraph {
            nodes: nodes,
            node_holes: nodes,
            edges: edges,
            edge_property: EdgeProperty::from(PhantomData::<Ty>),
        }
    }
}

impl<N, E, Ty, Ix> Serialize for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType + Serialize,
          N: Serialize,
          E: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        self.into_serializable().serialize(serializer)
    }
}

impl<'a, N, E, Ty, Ix> FromDeserialized for StableGraph<N, E, Ty, Ix>
    where Ix: IndexType,
          Ty: EdgeType,
{
    type Input = DeserStableGraph<N, E, Ix>;
    fn from_deserialized<E2>(input: Self::Input) -> Result<Self, E2>
        where E2: Error
    {
        let ty = PhantomData::<Ty>::from_deserialized(input.edge_property)?;
        let mut nodes = input.nodes;
        let node_holes = input.node_holes;
        let edges = input.edges;
        if edges.len() >= <Ix as IndexType>::max().index() {
            Err(invalid_length_err::<Ix, _>("edge", edges.len()))?
        }

        // insert Nones for each hole
        let mut offset = node_holes.len();
        let node_bound = node_holes.len() + nodes.len();
        for hole_pos in rev(node_holes) {
            offset -= 1;
            if hole_pos.index() >= node_bound {
                Err(invalid_node_err(hole_pos.index(), node_bound))?;
            }
            let insert_pos = hole_pos.index() - offset;
            nodes.insert(insert_pos, Node {
                weight: None,
                next: [EdgeIndex::end(); 2],
            });
        }

        if nodes.len() >= <Ix as IndexType>::max().index() {
            Err(invalid_length_err::<Ix, _>("node", nodes.len()))?
        }

        let node_bound = nodes.len();
        let mut sgr = StableGraph {
            g: Graph {
                nodes: nodes,
                edges: edges,
                ty: ty,
            },
            node_count: 0,
            edge_count: 0,
            free_edge: EdgeIndex::end(),
            free_node: NodeIndex::end(),
        };
        sgr.link_edges().map_err(|i| invalid_node_err(i.index(), node_bound))?;
        Ok(sgr)
    }
}

impl<'de, N, E, Ty, Ix> Deserialize<'de> for StableGraph<N, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType + Deserialize<'de>,
          N: Deserialize<'de>,
          E: Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        Self::from_deserialized(DeserStableGraph::deserialize(deserializer)?)
    }
}

#[test]
fn test_from_deserialized_with_holes() {
    use graph::node_index;
    use stable_graph::StableUnGraph;
    use serde::de::value::Error as SerdeError;
    use itertools::assert_equal;

    let input = DeserStableGraph::<_, (), u32> {
        nodes: vec![
            Node {
                weight: Some(1),
                next: [EdgeIndex::end(); 2],
            },
            Node {
                weight: Some(4),
                next: [EdgeIndex::end(); 2],
            },
            Node {
                weight: Some(5),
                next: [EdgeIndex::end(); 2],
            },
        ],
        node_holes: vec![
            node_index(0),
            node_index(2),
            node_index(3),
            node_index(6),
        ],
        edges: vec![],
        edge_property: EdgeProperty::Undirected,
    };
    let graph = StableUnGraph::from_deserialized::<SerdeError>(input).unwrap();

    assert_eq!(graph.node_count(), 3);
    assert_equal(
        graph.raw_nodes().iter().map(|n| n.weight.as_ref().cloned()),
        vec![None, Some(1), None, None, Some(4), Some(5), None]);
}

<|endoftext|>


<commit_before>// Copyright (c) 2018 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use clap;
use std::fs;
use std::io::Write;

use common::ui::{UI, Status};
use export_docker;
use export_docker::Result;
use export_k8s::{Manifest, ManifestJson};

use chartfile::ChartFile;
use values::Values;

pub struct Chart<'a> {
    name: String,
    chartfile: ChartFile,
    manifest_template: ManifestJson,
    values: Values,
    ui: &'a mut UI,
}

impl<'a> Chart<'a> {
    pub fn new_for_cli_matches(ui: &'a mut UI, matches: &clap::ArgMatches) -> Result<Self> {
        let image = if !matches.is_present("NO_DOCKER_IMAGE") {
            export_docker::export_for_cli_matches(ui, &matches)?
        } else {
            None
        };
        let manifest = Manifest::new_from_cli_matches(ui, &matches, image)?;

        let name = matches
            .value_of("CHART")
            .unwrap_or(&manifest.metadata_name)
            .to_string();
        let version = matches.value_of("VERSION");
        let description = matches.value_of("DESCRIPTION");
        let chartfile = ChartFile::new(&name, version, description);

        Ok(Self::new_for_manifest(manifest, name, chartfile, ui))
    }

    fn new_for_manifest(
        manifest: Manifest,
        name: String,
        chartfile: ChartFile,
        ui: &'a mut UI,
    ) -> Self {
        let main = json!({
            "metadata_name": "{{.Values.metadataName}}",
            "image": "{{.Values.imageName}}",
            "count": "{{.Values.instanceCount}}",
            "service_topology": "{{.Values.serviceTopology}}",
            "service_group": manifest.service_group.clone().map(|_| "{{.Values.serviceGroup}}"),
            "config": manifest.config
                .clone()
                .map(|_| "{{.Values.config}}"),
            "ring_secret_name": manifest.ring_secret_name
                .clone()
                .map(|_| "{{.Values.ringSecretName}}"),
            "bind": !manifest.binds.is_empty(),
        });

        let mut values = Values::new();
        values.add_entry("metadataName", &manifest.metadata_name);
        values.add_entry("imageName", &manifest.image);
        values.add_entry("instanceCount", &manifest.count.to_string());
        values.add_entry("serviceTopology", &manifest.service_topology.to_string());
        if let Some(ref group) = manifest.service_group {
            values.add_entry("serviceGroup", group);
        }
        if let Some(ref config) = manifest.config {
            values.add_entry("config", config);
        }
        if let Some(ref name) = manifest.ring_secret_name {
            values.add_entry("ringSecretName", name);
        }

        let mut binds = Vec::new();
        let mut i = 0;
        for bind in &manifest.binds {
            let name_var = format!("bindName{}", i);
            let service_var = format!("bindService{}", i);
            let group_var = format!("bindGroup{}", i);
            i = i + 1;

            values.add_entry(&name_var, &bind.name);
            values.add_entry(&service_var, &bind.service_group.service());
            values.add_entry(&group_var, &bind.service_group.group());

            let json = json!({
                "name": format!("{{{{.Values.{}}}}}", name_var),
                "service": format!("{{{{.Values.{}}}}}", service_var),
                "group": format!("{{{{.Values.{}}}}}", group_var),
            });

            binds.push(json);
        }

        let manifest_template = ManifestJson {
            main: main,
            binds: binds,
        };

        Chart {
            name,
            chartfile,
            manifest_template,
            values,
            ui,
        }
    }

    pub fn generate(mut self) -> Result<()> {
        self.ui.status(
            Status::Creating,
            format!("directory `{}`", self.name),
        )?;
        fs::create_dir_all(&self.name)?;

        self.generate_chartfile()?;

        self.generate_values()?;

        self.generate_manifest_template()
    }

    fn generate_chartfile(&mut self) -> Result<()> {
        let mut write = self.create_file("Chart.yaml")?;
        let out = self.chartfile.into_string()?;

        write.write(out.as_bytes())?;

        Ok(())
    }

    fn generate_manifest_template(self) -> Result<()> {
        let template_path = format!("{}/{}", self.name, "templates");
        self.ui.status(
            Status::Creating,
            format!("directory `{}`", template_path),
        )?;
        fs::create_dir_all(&template_path)?;

        let manifest_path = format!("{}/{}.yaml", template_path, self.name);
        self.ui.status(
            Status::Creating,
            format!("file `{}`", manifest_path),
        )?;
        let mut write = fs::File::create(manifest_path)?;
        let out: String = self.manifest_template.into();

        write.write(out.as_bytes())?;

        Ok(())
    }

    fn generate_values(&mut self) -> Result<()> {
        let mut write = self.create_file("values.yaml")?;
        self.values.generate(&mut write)?;

        Ok(())
    }

    fn create_file(&mut self, name: &str) -> Result<fs::File> {
        let path = format!("{}/{}", self.name, name);
        self.ui.status(Status::Creating, format!("file `{}`", path))?;

        fs::File::create(path).map_err(From::from)
    }
}
<commit_msg>pkg-export-helm: Don't consume self<commit_after>// Copyright (c) 2018 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use clap;
use std::fs;
use std::io::Write;

use common::ui::{UI, Status};
use export_docker;
use export_docker::Result;
use export_k8s::{Manifest, ManifestJson};

use chartfile::ChartFile;
use values::Values;

pub struct Chart<'a> {
    name: String,
    chartfile: ChartFile,
    manifest_template: Option<ManifestJson>,
    values: Values,
    ui: &'a mut UI,
}

impl<'a> Chart<'a> {
    pub fn new_for_cli_matches(ui: &'a mut UI, matches: &clap::ArgMatches) -> Result<Self> {
        let image = if !matches.is_present("NO_DOCKER_IMAGE") {
            export_docker::export_for_cli_matches(ui, &matches)?
        } else {
            None
        };
        let manifest = Manifest::new_from_cli_matches(ui, &matches, image)?;

        let name = matches
            .value_of("CHART")
            .unwrap_or(&manifest.metadata_name)
            .to_string();
        let version = matches.value_of("VERSION");
        let description = matches.value_of("DESCRIPTION");
        let chartfile = ChartFile::new(&name, version, description);

        Ok(Self::new_for_manifest(manifest, name, chartfile, ui))
    }

    fn new_for_manifest(
        manifest: Manifest,
        name: String,
        chartfile: ChartFile,
        ui: &'a mut UI,
    ) -> Self {
        let main = json!({
            "metadata_name": "{{.Values.metadataName}}",
            "image": "{{.Values.imageName}}",
            "count": "{{.Values.instanceCount}}",
            "service_topology": "{{.Values.serviceTopology}}",
            "service_group": manifest.service_group.clone().map(|_| "{{.Values.serviceGroup}}"),
            "config": manifest.config
                .clone()
                .map(|_| "{{.Values.config}}"),
            "ring_secret_name": manifest.ring_secret_name
                .clone()
                .map(|_| "{{.Values.ringSecretName}}"),
            "bind": !manifest.binds.is_empty(),
        });

        let mut values = Values::new();
        values.add_entry("metadataName", &manifest.metadata_name);
        values.add_entry("imageName", &manifest.image);
        values.add_entry("instanceCount", &manifest.count.to_string());
        values.add_entry("serviceTopology", &manifest.service_topology.to_string());
        if let Some(ref group) = manifest.service_group {
            values.add_entry("serviceGroup", group);
        }
        if let Some(ref config) = manifest.config {
            values.add_entry("config", config);
        }
        if let Some(ref name) = manifest.ring_secret_name {
            values.add_entry("ringSecretName", name);
        }

        let mut binds = Vec::new();
        let mut i = 0;
        for bind in &manifest.binds {
            let name_var = format!("bindName{}", i);
            let service_var = format!("bindService{}", i);
            let group_var = format!("bindGroup{}", i);
            i = i + 1;

            values.add_entry(&name_var, &bind.name);
            values.add_entry(&service_var, &bind.service_group.service());
            values.add_entry(&group_var, &bind.service_group.group());

            let json = json!({
                "name": format!("{{{{.Values.{}}}}}", name_var),
                "service": format!("{{{{.Values.{}}}}}", service_var),
                "group": format!("{{{{.Values.{}}}}}", group_var),
            });

            binds.push(json);
        }

        let manifest_template = Some(ManifestJson {
            main: main,
            binds: binds,
        });

        Chart {
            name,
            chartfile,
            manifest_template,
            values,
            ui,
        }
    }

    pub fn generate(mut self) -> Result<()> {
        self.ui.status(
            Status::Creating,
            format!("directory `{}`", self.name),
        )?;
        fs::create_dir_all(&self.name)?;

        self.generate_chartfile()?;

        self.generate_values()?;

        self.generate_manifest_template()
    }

    fn generate_chartfile(&mut self) -> Result<()> {
        let mut write = self.create_file("Chart.yaml")?;
        let out = self.chartfile.into_string()?;

        write.write(out.as_bytes())?;

        Ok(())
    }

    fn generate_manifest_template(&mut self) -> Result<()> {
        let template_path = format!("{}/{}", self.name, "templates");
        self.ui.status(
            Status::Creating,
            format!("directory `{}`", template_path),
        )?;
        fs::create_dir_all(&template_path)?;

        let manifest_path = format!("{}/{}.yaml", template_path, self.name);
        self.ui.status(
            Status::Creating,
            format!("file `{}`", manifest_path),
        )?;
        let mut write = fs::File::create(manifest_path)?;
        let out: String = self.manifest_template
            .take()
            .expect("generate_manifest_template() called more than once")
            .into();

        write.write(out.as_bytes())?;

        Ok(())
    }

    fn generate_values(&mut self) -> Result<()> {
        let mut write = self.create_file("values.yaml")?;
        self.values.generate(&mut write)?;

        Ok(())
    }

    fn create_file(&mut self, name: &str) -> Result<fs::File> {
        let path = format!("{}/{}", self.name, name);
        self.ui.status(Status::Creating, format!("file `{}`", path))?;

        fs::File::create(path).map_err(From::from)
    }
}
<|endoftext|>


<commit_before>extern crate regex;

use regex::Regex;
use std::env::args;

fn has_bad_characters(s: &String) -> bool {
    let bad_re = Regex::new(r"(?:(ab)|(cd)|(pq)|(xy))").unwrap();
    bad_re.is_match(&s)
}

fn at_least_three_vowels(s: &String) -> bool {
    // regex wasn't working here for some reason, and it's a linear pass
    // anyways
    s.chars().filter(
        |c| match *c {
            'a' | 'e' | 'i' | 'o' | 'u' => true,
            _                           => false,
        }
    ).count() >= 3
}

fn at_least_one_duplicate(s: &String) -> bool {
    let mut iter = s.chars().peekable();
    while iter.peek().is_some() {
        let c = iter.next().unwrap();
        if iter.peek().is_some() && c == *iter.peek().unwrap() {
            return true
        }
    }
    false
}

fn is_nice(s: &String) -> bool {
    !has_bad_characters(s) &&
        at_least_three_vowels(s) &&
        at_least_one_duplicate(s)
}

fn main() {
    let num = args().skip(1).filter(is_nice).count();
    println!("{}", num);
}
<commit_msg>day 5, part 2. sad rust doesn't support backref regexes, but i get why<commit_after>#![feature(str_char)]
extern crate regex;

use regex::Regex;
use std::env::args;

fn has_bad_characters(s: &String) -> bool {
    let bad_re = Regex::new(r"(?:(ab)|(cd)|(pq)|(xy))").unwrap();
    bad_re.is_match(&s)
}

fn at_least_three_vowels(s: &String) -> bool {
    // regex wasn't working here for some reason, and it's a linear pass
    // anyways
    s.chars().filter(
        |c| match *c {
            'a' | 'e' | 'i' | 'o' | 'u' => true,
            _                           => false,
        }
    ).count() >= 3
}

fn at_least_one_duplicate(s: &String) -> bool {
    let mut iter = s.chars().peekable();
    while iter.peek().is_some() {
        let c = iter.next().unwrap();
        if iter.peek().is_some() && c == *iter.peek().unwrap() {
            return true
        }
    }
    false
}

fn is_nice(s: &String) -> bool {
    /*
    !has_bad_characters(s) &&
        at_least_three_vowels(s) &&
        at_least_one_duplicate(s)
    */
    sandwiched(s) && repeat_pair(s)
}

fn sandwiched(s: &String) -> bool {
    // rust only supports RE2 regexes, so not backreffing on capture groups
    // otherwise this can just be: (.+).\1
    (1..(s.len() - 1)).any(|i| s.char_at(i - 1) == s.char_at(i + 1))
}

fn repeat_pair(s: &String) -> bool {
    // posix regex: (.)(.).*\1\2
    (0..(s.len() - 3)).any(
        |i| {
            let c1 = s.char_at(i);
            let c2 = s.char_at(i + 1);
            ((i + 2)..(s.len() - 1)).any(
                |j| {
                    let c3 = s.char_at(j);
                    let c4 = s.char_at(j + 1);
                    c1 == c3 && c2 == c4
                }
            )
        }
    )
}

fn main() {
    let num = args().skip(1).filter(is_nice).count();
    println!("{}", num);
}
<|endoftext|>


<commit_before>//! # Serde JSON
//!
//! JSON is a ubiquitous open-standard format that uses human-readable text to
//! transmit data objects consisting of key-value pairs.
//!
//! ```json,ignore
//! {
//!   "name": "John Doe",
//!   "age": 43,
//!   "address": {
//!     "street": "10 Downing Street",
//!     "city": "London"
//!   },
//!   "phones": [
//!     "+44 1234567",
//!     "+44 2345678"
//!   ]
//! }
//! ```
//!
//! There are three common ways that you might find yourself needing to work
//! with JSON data in Rust.
//!
//!  - **As text data.** An unprocessed string of JSON data that you receive on
//!    an HTTP endpoint, read from a file, or prepare to send to a remote
//!    server.
//!  - **As an untyped or loosely typed representation.** Maybe you want to
//!    check that some JSON data is valid before passing it on, but without
//!    knowing the structure of what it contains. Or you want to do very basic
//!    manipulations like add a level of nesting.
//!  - **As a strongly typed Rust data structure.** When you expect all or most
//!    of your data to conform to a particular structure and want to get real
//!    work done without JSON's loosey-goosey nature tripping you up.
//!
//! Serde JSON provides efficient, flexible, safe ways of converting data
//! between each of these representations.
//!
//! # JSON to the Value enum
//!
//! Any valid JSON data can be manipulated in the following recursive enum
//! representation. This data structure is [`serde_json::Value`][value].
//!
//! ```rust,ignore
//! enum Value {
//!     Null,
//!     Bool(bool),
//!     Number(Number),
//!     String(String),
//!     Array(Vec<Value>),
//!     Object(Map<String, Value>),
//! }
//! ```
//!
//! A string of JSON data can be parsed into a `serde_json::Value` by the
//! [`serde_json::from_str`][from_str] function. There is also
//! [`from_slice`][from_slice] for parsing from a byte slice &[u8],
//! [`from_iter`][from_iter] for parsing from an iterator of bytes, and
//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
//! a TCP stream.
//!
//! ```rust
//! # extern crate serde_json;
//! # use serde_json::Error;
//! # pub fn example() -> Result<(), Error> {
//! use serde_json::Value;
//!
//! let data = r#" { "name": "John Doe", "age": 43, ... } "#;
//! let v: Value = serde_json::from_str(data)?;
//! println!("Please call {} at the number {}", v["name"], v["phones"][0]);
//! # Ok(()) }
//! # fn main() {}
//! ```
//!
//! The `Value` representation is sufficient for very basic tasks but is brittle
//! and tedious to work with. Error handling is verbose to implement correctly,
//! for example imagine trying to detect the presence of unrecognized fields in
//! the input data. The compiler is powerless to help you when you make a
//! mistake, for example imagine typoing `v["name"]` as `v["nmae"]` in one of
//! the dozens of places it is used in your code.
//!
//! # JSON to strongly typed data structures
//!
//! Serde provides a powerful way of mapping JSON data into Rust data structures
//! largely automatically.
//!
//! ```rust
//! # extern crate serde_json;
//! # #[macro_use] extern crate serde_derive;
//! # use serde_json::Error;
//! # pub fn example() -> Result<(), Error> {
//! #[derive(Serialize, Deserialize)]
//! struct Person {
//!     name: String,
//!     age: u8,
//!     address: Address,
//!     phones: Vec<String>,
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Address {
//!     street: String,
//!     city: String,
//! }
//!
//! let data = r#" { "name": "John Doe", "age": 43, ... } "#;
//! let p: Person = serde_json::from_str(data)?;
//! println!("Please call {} at the number {}", p.name, p.phones[0]);
//! # Ok(()) }
//! # fn main() {}
//! ```
//!
//! This is the same `serde_json::from_str` function as before, but this time we
//! assign the return value to a variable of type `Person` so Serde JSON will
//! automatically interpret the input data as a `Person` and produce informative
//! error messages if the layout does not conform to what a `Person` is expected
//! to look like.
//!
//! Any type that implements Serde's `Deserialize` trait can be deserialized
//! this way. This includes built-in Rust standard library types like `Vec<T>`
//! and `HashMap<K, V>`, as well as any structs or enums annotated with
//! `#[derive(Deserialize)]`.
//!
//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us
//! use it correctly like they do for any other Rust code. The IDE can
//! autocomplete field names to prevent typos, which was impossible in the
//! `serde_json::Value` representation. And the Rust compiler can check that
//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a
//! `Vec<String>` so indexing into it makes sense and produces a `String`.
//!
//! # Constructing JSON
//!
//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
//! objects with very natural JSON syntax. In order to use this macro,
//! `serde_json` needs to be imported with the `#[macro_use]` attribute.
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_json;
//!
//! fn main() {
//!     // The type of `john` is `serde_json::Value`
//!     let john = json!({
//!       "name": "John Doe",
//!       "age": 43,
//!       "phones": [
//!         "+44 1234567",
//!         "+44 2345678"
//!       ]
//!     });
//!
//!     println!("first phone number: {}", john["phones"][0]);
//!
//!     // Convert to a string of JSON and print it out
//!     println!("{}", john.to_string());
//! }
//! ```
//!
//! The `Value::to_string()` function converts a `serde_json::Value` into a
//! `String` of JSON text.
//!
//! One neat thing about the `json!` macro is that variables and expressions can
//! be interpolated directly into the JSON value as you are building it. Serde
//! will check at compile time that the value you are interpolating is able to
//! be represented as JSON.
//!
//! ```rust
//! # #[macro_use] extern crate serde_json;
//! # fn random_phone() -> u16 { 0 }
//! # fn main() {
//! let full_name = "John Doe";
//! let age_last_year = 42;
//!
//! // The type of `john` is `serde_json::Value`
//! let john = json!({
//!   "name": full_name,
//!   "age": age_last_year + 1,
//!   "phones": [
//!     format!("+44 {}", random_phone())
//!   ]
//! });
//! # let _ = john;
//! # }
//! ```
//!
//! This is amazingly convenient but we have the problem we had before with
//! `Value` which is that the IDE and Rust compiler cannot help us if we get it
//! wrong. Serde JSON provides a better way of serializing strongly-typed data
//! structures into JSON text.
//!
//! # Serializing data structures
//!
//! A data structure can be converted to a JSON string by
//! [`serde_json::to_string`][to_string]. There is also
//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
//! such as a File or a TCP stream.
//!
//! ```rust
//! # extern crate serde_json;
//! # #[macro_use] extern crate serde_derive;
//! # use serde_json::Error;
//! # pub fn example() -> Result<String, Error> {
//! #[derive(Serialize, Deserialize)]
//! struct Address {
//!     street: String,
//!     city: String,
//! }
//!
//! let address = Address {
//!     street: "10 Downing Street".to_owned(),
//!     city: "London".to_owned(),
//! };
//!
//! let j = serde_json::to_string(&address)?;
//! # Ok(j) }
//! # fn main() {}
//! ```
//!
//! Any type that implements Serde's `Serialize` trait can be serialized this
//! way. This includes built-in Rust standard library types like `Vec<T>` and
//! `HashMap<K, V>`, as well as any structs or enums annotated with
//! `#[derive(Serialize)]`.
//!
//! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html
//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
//! [from_iter]: https://docs.serde.rs/serde_json/de/fn.from_iter.html
//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
//! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
//! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html
//! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html
//! [macro]: https://docs.serde.rs/serde_json/macro.json.html

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy, clippy_pedantic))]
// Because of "JavaScript"... fixed in Manishearth/rust-clippy#1071
#![cfg_attr(feature = "clippy", allow(doc_markdown))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "clippy", allow(
// Deserializer::from_str, from_iter, into_iter
    should_implement_trait,
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// string ser/de uses indexing and slicing
    indexing_slicing,
// things are often more readable this way
    shadow_reuse,
    shadow_unrelated,
    single_match_else,
    stutter,
// not practical
    missing_docs_in_private_items,
))]

#![deny(missing_docs)]

extern crate num_traits;
extern crate core;
#[macro_use]
extern crate serde;
extern crate itoa;
extern crate dtoa;
#[cfg(feature = "preserve_order")]
extern crate linked_hash_map;

pub use self::de::{Deserializer, StreamDeserializer, from_iter, from_reader,
                   from_slice, from_str};
pub use self::error::{Error, Result};
pub use self::ser::{Serializer, to_string, to_string_pretty, to_vec,
                    to_vec_pretty, to_writer, to_writer_pretty};
pub use self::value::{Map, Number, Value, from_value, to_value};

#[macro_use]
mod macros;

pub mod de;
pub mod error;
pub mod ser;
pub mod value;

mod map;
mod number;
mod read;
<commit_msg>Don't ignore Rust doc example.<commit_after>//! # Serde JSON
//!
//! JSON is a ubiquitous open-standard format that uses human-readable text to
//! transmit data objects consisting of key-value pairs.
//!
//! ```json,ignore
//! {
//!   "name": "John Doe",
//!   "age": 43,
//!   "address": {
//!     "street": "10 Downing Street",
//!     "city": "London"
//!   },
//!   "phones": [
//!     "+44 1234567",
//!     "+44 2345678"
//!   ]
//! }
//! ```
//!
//! There are three common ways that you might find yourself needing to work
//! with JSON data in Rust.
//!
//!  - **As text data.** An unprocessed string of JSON data that you receive on
//!    an HTTP endpoint, read from a file, or prepare to send to a remote
//!    server.
//!  - **As an untyped or loosely typed representation.** Maybe you want to
//!    check that some JSON data is valid before passing it on, but without
//!    knowing the structure of what it contains. Or you want to do very basic
//!    manipulations like add a level of nesting.
//!  - **As a strongly typed Rust data structure.** When you expect all or most
//!    of your data to conform to a particular structure and want to get real
//!    work done without JSON's loosey-goosey nature tripping you up.
//!
//! Serde JSON provides efficient, flexible, safe ways of converting data
//! between each of these representations.
//!
//! # JSON to the Value enum
//!
//! Any valid JSON data can be manipulated in the following recursive enum
//! representation. This data structure is [`serde_json::Value`][value].
//!
//! ```rust
//! # use serde_json::{Number, Map};
//! # #[allow(dead_code)]
//! enum Value {
//!     Null,
//!     Bool(bool),
//!     Number(Number),
//!     String(String),
//!     Array(Vec<Value>),
//!     Object(Map<String, Value>),
//! }
//! ```
//!
//! A string of JSON data can be parsed into a `serde_json::Value` by the
//! [`serde_json::from_str`][from_str] function. There is also
//! [`from_slice`][from_slice] for parsing from a byte slice &[u8],
//! [`from_iter`][from_iter] for parsing from an iterator of bytes, and
//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
//! a TCP stream.
//!
//! ```rust
//! # extern crate serde_json;
//! # use serde_json::Error;
//! # pub fn example() -> Result<(), Error> {
//! use serde_json::Value;
//!
//! let data = r#" { "name": "John Doe", "age": 43, ... } "#;
//! let v: Value = serde_json::from_str(data)?;
//! println!("Please call {} at the number {}", v["name"], v["phones"][0]);
//! # Ok(()) }
//! # fn main() {}
//! ```
//!
//! The `Value` representation is sufficient for very basic tasks but is brittle
//! and tedious to work with. Error handling is verbose to implement correctly,
//! for example imagine trying to detect the presence of unrecognized fields in
//! the input data. The compiler is powerless to help you when you make a
//! mistake, for example imagine typoing `v["name"]` as `v["nmae"]` in one of
//! the dozens of places it is used in your code.
//!
//! # JSON to strongly typed data structures
//!
//! Serde provides a powerful way of mapping JSON data into Rust data structures
//! largely automatically.
//!
//! ```rust
//! # extern crate serde_json;
//! # #[macro_use] extern crate serde_derive;
//! # use serde_json::Error;
//! # pub fn example() -> Result<(), Error> {
//! #[derive(Serialize, Deserialize)]
//! struct Person {
//!     name: String,
//!     age: u8,
//!     address: Address,
//!     phones: Vec<String>,
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Address {
//!     street: String,
//!     city: String,
//! }
//!
//! let data = r#" { "name": "John Doe", "age": 43, ... } "#;
//! let p: Person = serde_json::from_str(data)?;
//! println!("Please call {} at the number {}", p.name, p.phones[0]);
//! # Ok(()) }
//! # fn main() {}
//! ```
//!
//! This is the same `serde_json::from_str` function as before, but this time we
//! assign the return value to a variable of type `Person` so Serde JSON will
//! automatically interpret the input data as a `Person` and produce informative
//! error messages if the layout does not conform to what a `Person` is expected
//! to look like.
//!
//! Any type that implements Serde's `Deserialize` trait can be deserialized
//! this way. This includes built-in Rust standard library types like `Vec<T>`
//! and `HashMap<K, V>`, as well as any structs or enums annotated with
//! `#[derive(Deserialize)]`.
//!
//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us
//! use it correctly like they do for any other Rust code. The IDE can
//! autocomplete field names to prevent typos, which was impossible in the
//! `serde_json::Value` representation. And the Rust compiler can check that
//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a
//! `Vec<String>` so indexing into it makes sense and produces a `String`.
//!
//! # Constructing JSON
//!
//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
//! objects with very natural JSON syntax. In order to use this macro,
//! `serde_json` needs to be imported with the `#[macro_use]` attribute.
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_json;
//!
//! fn main() {
//!     // The type of `john` is `serde_json::Value`
//!     let john = json!({
//!       "name": "John Doe",
//!       "age": 43,
//!       "phones": [
//!         "+44 1234567",
//!         "+44 2345678"
//!       ]
//!     });
//!
//!     println!("first phone number: {}", john["phones"][0]);
//!
//!     // Convert to a string of JSON and print it out
//!     println!("{}", john.to_string());
//! }
//! ```
//!
//! The `Value::to_string()` function converts a `serde_json::Value` into a
//! `String` of JSON text.
//!
//! One neat thing about the `json!` macro is that variables and expressions can
//! be interpolated directly into the JSON value as you are building it. Serde
//! will check at compile time that the value you are interpolating is able to
//! be represented as JSON.
//!
//! ```rust
//! # #[macro_use] extern crate serde_json;
//! # fn random_phone() -> u16 { 0 }
//! # fn main() {
//! let full_name = "John Doe";
//! let age_last_year = 42;
//!
//! // The type of `john` is `serde_json::Value`
//! let john = json!({
//!   "name": full_name,
//!   "age": age_last_year + 1,
//!   "phones": [
//!     format!("+44 {}", random_phone())
//!   ]
//! });
//! # let _ = john;
//! # }
//! ```
//!
//! This is amazingly convenient but we have the problem we had before with
//! `Value` which is that the IDE and Rust compiler cannot help us if we get it
//! wrong. Serde JSON provides a better way of serializing strongly-typed data
//! structures into JSON text.
//!
//! # Serializing data structures
//!
//! A data structure can be converted to a JSON string by
//! [`serde_json::to_string`][to_string]. There is also
//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
//! such as a File or a TCP stream.
//!
//! ```rust
//! # extern crate serde_json;
//! # #[macro_use] extern crate serde_derive;
//! # use serde_json::Error;
//! # pub fn example() -> Result<String, Error> {
//! #[derive(Serialize, Deserialize)]
//! struct Address {
//!     street: String,
//!     city: String,
//! }
//!
//! let address = Address {
//!     street: "10 Downing Street".to_owned(),
//!     city: "London".to_owned(),
//! };
//!
//! let j = serde_json::to_string(&address)?;
//! # Ok(j) }
//! # fn main() {}
//! ```
//!
//! Any type that implements Serde's `Serialize` trait can be serialized this
//! way. This includes built-in Rust standard library types like `Vec<T>` and
//! `HashMap<K, V>`, as well as any structs or enums annotated with
//! `#[derive(Serialize)]`.
//!
//! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html
//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
//! [from_iter]: https://docs.serde.rs/serde_json/de/fn.from_iter.html
//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
//! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
//! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html
//! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html
//! [macro]: https://docs.serde.rs/serde_json/macro.json.html

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy, clippy_pedantic))]
// Because of "JavaScript"... fixed in Manishearth/rust-clippy#1071
#![cfg_attr(feature = "clippy", allow(doc_markdown))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "clippy", allow(
// Deserializer::from_str, from_iter, into_iter
    should_implement_trait,
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// string ser/de uses indexing and slicing
    indexing_slicing,
// things are often more readable this way
    shadow_reuse,
    shadow_unrelated,
    single_match_else,
    stutter,
// not practical
    missing_docs_in_private_items,
))]

#![deny(missing_docs)]

extern crate num_traits;
extern crate core;
#[macro_use]
extern crate serde;
extern crate itoa;
extern crate dtoa;
#[cfg(feature = "preserve_order")]
extern crate linked_hash_map;

pub use self::de::{Deserializer, StreamDeserializer, from_iter, from_reader,
                   from_slice, from_str};
pub use self::error::{Error, Result};
pub use self::ser::{Serializer, to_string, to_string_pretty, to_vec,
                    to_vec_pretty, to_writer, to_writer_pretty};
pub use self::value::{Map, Number, Value, from_value, to_value};

#[macro_use]
mod macros;

pub mod de;
pub mod error;
pub mod ser;
pub mod value;

mod map;
mod number;
mod read;
<|endoftext|>


<commit_before>#![feature(std_misc)]
pub mod string_generator {
    use std::collections::HashMap;
    use std::collections::hash_map::Entry::{Occupied, Vacant};
    pub struct StrGen {
        counter: HashMap<String, u64>
    }
    impl StrGen {
        pub fn generate(&mut self, prefix: &str) -> String {
            let count = match self.counter.entry(prefix.to_string()) {

                Vacant(x) => *x.insert(1),
                Occupied(mut x) => {
                    let nextval = x.get() + 1;
                    x.insert(nextval);
                    nextval
                }
            };
            format!("{}{}", prefix, count)
        }
    }

    pub fn generator() -> StrGen {
        StrGen { counter: HashMap::new() }
    }
}

fn main() {
    let mut gen = string_generator::generator();
    println!("{}", gen.generate("abc"));
    println!("{}", gen.generate("abc"));
    println!("{}", gen.generate("def"));
    println!("{}", gen.generate("abc"));
    println!("{}", gen.generate("def"));
    println!("{}", gen.generate("ghi"));
}
<commit_msg>Fix minor bug<commit_after>#![feature(std_misc)]
pub mod string_generator {
    use std::collections::HashMap;
    use std::collections::hash_map::Entry::{Occupied, Vacant};
    pub struct StrGen {
        counter: HashMap<String, u64>
    }
    impl StrGen {
        pub fn generate(&mut self, prefix: &str) -> String {
            let count = match self.counter.entry(prefix.to_string()) {

                Vacant(x) => *x.insert(1),
                Occupied(mut x) => {
                    let nextval = x.get() + 1;
                    x.insert(nextval);
                    nextval
                }
            };
            format!("{}{}", prefix, count)
        }
    }

    pub fn generator() -> StrGen {
        StrGen { counter: HashMap::new() }
    }
}

<|endoftext|>


<commit_before>fn main() {
    println!("Hello, World!");
}<commit_msg>#1 removed foo.rs<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! An implementation of `VatNetwork` for the common case of a client-server connection.

use capnp::message::ReaderOptions;
use capnp::capability::Promise;
use futures::{AsyncRead, AsyncWrite, FutureExt, TryFutureExt};
use futures::channel::oneshot;

use std::cell::RefCell;
use std::rc::{Rc, Weak};

pub type VatId = crate::rpc_twoparty_capnp::Side;

struct IncomingMessage {
    message: ::capnp::message::Reader<capnp::serialize::OwnedSegments>,
}

impl IncomingMessage {
    pub fn new(message: ::capnp::message::Reader<capnp::serialize::OwnedSegments>) -> IncomingMessage {
        IncomingMessage { message: message }
    }
}

impl crate::IncomingMessage for IncomingMessage {
    fn get_body<'a>(&'a self) -> ::capnp::Result<::capnp::any_pointer::Reader<'a>> {
        self.message.get_root()
    }
}

struct OutgoingMessage {
    message: ::capnp::message::Builder<::capnp::message::HeapAllocator>,
    sender: ::capnp_futures::Sender<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>>,
}

impl crate::OutgoingMessage for OutgoingMessage {
    fn get_body<'a>(&'a mut self) -> ::capnp::Result<::capnp::any_pointer::Builder<'a>> {
        self.message.get_root()
    }

    fn get_body_as_reader<'a>(&'a self) -> ::capnp::Result<::capnp::any_pointer::Reader<'a>> {
        self.message.get_root_as_reader()
    }

    fn send(self: Box<Self>)
            ->
        (Promise<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, ::capnp::Error>,
         Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>)
    {
        let tmp = *self;
        let OutgoingMessage {message, mut sender} = tmp;
        let m = Rc::new(message);
        (Promise::from_future(sender.send(m.clone()).map_err(|e| e.into())), m)
    }

    fn take(self: Box<Self>)
            -> ::capnp::message::Builder<::capnp::message::HeapAllocator>
    {
        self.message
    }
}

struct ConnectionInner<T> where T: AsyncRead + 'static {
    input_stream: Rc<RefCell<Option<T>>>,
    sender: ::capnp_futures::Sender<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>>,
    side: crate::rpc_twoparty_capnp::Side,
    receive_options: ReaderOptions,
    on_disconnect_fulfiller: Option<oneshot::Sender<()>>,
}

struct Connection<T> where T: AsyncRead + 'static {
    inner: Rc<RefCell<ConnectionInner<T>>>,
}

impl <T> Drop for ConnectionInner<T> where T: AsyncRead {
    fn drop(&mut self) {
        let maybe_fulfiller = ::std::mem::replace(&mut self.on_disconnect_fulfiller, None);
        match maybe_fulfiller {
            Some(fulfiller) => {
                let _ = fulfiller.send(());
            }
            None => unreachable!(),
        }
    }
}

impl <T> Connection<T> where T: AsyncRead {
    fn new(input_stream: T,
           sender: ::capnp_futures::Sender<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>>,
           side: crate::rpc_twoparty_capnp::Side,
           receive_options: ReaderOptions,
           on_disconnect_fulfiller: oneshot::Sender<()>,
           ) -> Connection<T>
    {

        Connection {
            inner: Rc::new(RefCell::new(
                ConnectionInner {
                    input_stream: Rc::new(RefCell::new(Some(input_stream))),
                    sender: sender,
                    side: side,
                    receive_options: receive_options,
                    on_disconnect_fulfiller: Some(on_disconnect_fulfiller),
                })),
        }
    }
}

impl <T> crate::Connection<crate::rpc_twoparty_capnp::Side> for Connection<T>
    where T: AsyncRead + Unpin
{
    fn get_peer_vat_id(&self) -> crate::rpc_twoparty_capnp::Side {
        self.inner.borrow().side
    }

    fn new_outgoing_message(&mut self, _first_segment_word_size: u32) -> Box<dyn crate::OutgoingMessage> {
        Box::new(OutgoingMessage {
            message: ::capnp::message::Builder::new_default(),
            sender: self.inner.borrow().sender.clone(),
        })
    }

    fn receive_incoming_message(&mut self) -> Promise<Option<Box<dyn crate::IncomingMessage + 'static>>, ::capnp::Error> {
        let inner = self.inner.borrow_mut();
        let maybe_input_stream = ::std::mem::replace(&mut *inner.input_stream.borrow_mut(), None);
        let return_it_here = inner.input_stream.clone();
        match maybe_input_stream {
            Some(mut s) => {
                let receive_options = inner.receive_options;
                Promise::from_future(async move {
                    let maybe_message = ::capnp_futures::serialize::read_message(&mut s, receive_options).await?;
                    *return_it_here.borrow_mut() = Some(s);
                    Ok(maybe_message.map(|message|
                                         Box::new(IncomingMessage::new(message)) as Box<dyn crate::IncomingMessage>))
                })
            }
            None => {
                Promise::err(::capnp::Error::failed("this should not be possible".to_string()))
             //   unreachable!(),
            }
        }
    }

    fn shutdown(&mut self, result: ::capnp::Result<()>) -> Promise<(), ::capnp::Error> {
        Promise::from_future(self.inner.borrow_mut().sender.terminate(result).map_err(|e| e.into()))
    }
}

/// A vat networks with two parties, the client and the server.
pub struct VatNetwork<T> where T: AsyncRead + 'static + Unpin {
    connection: Option<Connection<T>>,

    // HACK
    weak_connection_inner: Weak<RefCell<ConnectionInner<T>>>,

    execution_driver: futures::future::Shared<Promise<(), ::capnp::Error>>,
    side: crate::rpc_twoparty_capnp::Side,
}

impl <T> VatNetwork<T> where T: AsyncRead + Unpin {
    /// Creates a new two-party vat network that will receive data on `input_stream` and send data on
    /// `output_stream`.
    ///
    /// `side` indicates whether this is the client or the server side of the connection. This has no
    /// effect on the data sent over the connection; it merely exists so that `RpcNetwork::bootstrap` knows
    /// whether to return the local or the remote bootstrap capability. `VatId` parameters like this one
    /// will make more sense once we have vat networks with more than two parties.
    ///
    /// The options in `receive_options` will be used when reading the messages that come in on `input_stream`.
    pub fn new<U>(input_stream: T,
               output_stream: U,
               side: crate::rpc_twoparty_capnp::Side,
               receive_options: ReaderOptions) -> VatNetwork<T>
        where U: AsyncWrite + 'static + Unpin,
    {

        let (fulfiller, disconnect_promise) = oneshot::channel();
        let disconnect_promise = disconnect_promise
            .map_err(|_| ::capnp::Error::disconnected("disconnected".into()));

        let (execution_driver, sender) = {
            let (tx, write_queue) = ::capnp_futures::write_queue(output_stream);

            // Don't use `.join()` here because we need to make sure to wait for `disconnect_promise` to
            // resolve even if `write_queue` resolves to an error.
            (Promise::from_future(
                write_queue
                    .then(move |r| disconnect_promise.then(move |_| futures::future::ready(r)).map_ok(|_| ()))).shared(),
             tx)
        };

        let connection = Connection::new(input_stream, sender, side, receive_options, fulfiller);
        let weak_inner = Rc::downgrade(&connection.inner);
        VatNetwork {
            connection: Some(connection),
            weak_connection_inner: weak_inner,
            execution_driver: execution_driver,
            side: side,
        }
    }
}

impl <T> crate::VatNetwork<VatId> for VatNetwork<T>
    where T: AsyncRead + Unpin
{
    fn connect(&mut self, host_id: VatId) -> Option<Box<dyn crate::Connection<VatId>>> {
        if host_id == self.side {
            None
        } else {
            let connection = ::std::mem::replace(&mut self.connection, None);
            match connection {
                Some(c) => {
                    Some(Box::new(c))
                } None => {
                    match self.weak_connection_inner.upgrade() {
                        Some(connection_inner) => {
                            Some(Box::new(Connection { inner: connection_inner }))
                        }
                        None => {
                            panic!("tried to reconnect a disconnected twoparty vat network.")
                        }
                    }
                }
            }
        }
    }

    fn accept(&mut self) -> Promise<Box<dyn crate::Connection<VatId>>, ::capnp::Error> {
        let connection = ::std::mem::replace(&mut self.connection, None);
        match connection {
            Some(c) => Promise::ok(Box::new(c) as Box<dyn crate::Connection<VatId>>),
            None => Promise::from_future(::futures::future::pending()),
        }
    }

    fn drive_until_shutdown(&mut self) -> Promise<(), ::capnp::Error> {
        Promise::from_future(self.execution_driver.clone())
    }
}
<commit_msg>oops, apparently the mut is needed for older rustc<commit_after>// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! An implementation of `VatNetwork` for the common case of a client-server connection.

use capnp::message::ReaderOptions;
use capnp::capability::Promise;
use futures::{AsyncRead, AsyncWrite, FutureExt, TryFutureExt};
use futures::channel::oneshot;

use std::cell::RefCell;
use std::rc::{Rc, Weak};

pub type VatId = crate::rpc_twoparty_capnp::Side;

struct IncomingMessage {
    message: ::capnp::message::Reader<capnp::serialize::OwnedSegments>,
}

impl IncomingMessage {
    pub fn new(message: ::capnp::message::Reader<capnp::serialize::OwnedSegments>) -> IncomingMessage {
        IncomingMessage { message: message }
    }
}

impl crate::IncomingMessage for IncomingMessage {
    fn get_body<'a>(&'a self) -> ::capnp::Result<::capnp::any_pointer::Reader<'a>> {
        self.message.get_root()
    }
}

struct OutgoingMessage {
    message: ::capnp::message::Builder<::capnp::message::HeapAllocator>,
    sender: ::capnp_futures::Sender<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>>,
}

impl crate::OutgoingMessage for OutgoingMessage {
    fn get_body<'a>(&'a mut self) -> ::capnp::Result<::capnp::any_pointer::Builder<'a>> {
        self.message.get_root()
    }

    fn get_body_as_reader<'a>(&'a self) -> ::capnp::Result<::capnp::any_pointer::Reader<'a>> {
        self.message.get_root_as_reader()
    }

    fn send(self: Box<Self>)
            ->
        (Promise<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>, ::capnp::Error>,
         Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>)
    {
        let tmp = *self;
        let OutgoingMessage {message, mut sender} = tmp;
        let m = Rc::new(message);
        (Promise::from_future(sender.send(m.clone()).map_err(|e| e.into())), m)
    }

    fn take(self: Box<Self>)
            -> ::capnp::message::Builder<::capnp::message::HeapAllocator>
    {
        self.message
    }
}

struct ConnectionInner<T> where T: AsyncRead + 'static {
    input_stream: Rc<RefCell<Option<T>>>,
    sender: ::capnp_futures::Sender<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>>,
    side: crate::rpc_twoparty_capnp::Side,
    receive_options: ReaderOptions,
    on_disconnect_fulfiller: Option<oneshot::Sender<()>>,
}

struct Connection<T> where T: AsyncRead + 'static {
    inner: Rc<RefCell<ConnectionInner<T>>>,
}

impl <T> Drop for ConnectionInner<T> where T: AsyncRead {
    fn drop(&mut self) {
        let maybe_fulfiller = ::std::mem::replace(&mut self.on_disconnect_fulfiller, None);
        match maybe_fulfiller {
            Some(fulfiller) => {
                let _ = fulfiller.send(());
            }
            None => unreachable!(),
        }
    }
}

impl <T> Connection<T> where T: AsyncRead {
    fn new(input_stream: T,
           sender: ::capnp_futures::Sender<Rc<::capnp::message::Builder<::capnp::message::HeapAllocator>>>,
           side: crate::rpc_twoparty_capnp::Side,
           receive_options: ReaderOptions,
           on_disconnect_fulfiller: oneshot::Sender<()>,
           ) -> Connection<T>
    {

        Connection {
            inner: Rc::new(RefCell::new(
                ConnectionInner {
                    input_stream: Rc::new(RefCell::new(Some(input_stream))),
                    sender: sender,
                    side: side,
                    receive_options: receive_options,
                    on_disconnect_fulfiller: Some(on_disconnect_fulfiller),
                })),
        }
    }
}

impl <T> crate::Connection<crate::rpc_twoparty_capnp::Side> for Connection<T>
    where T: AsyncRead + Unpin
{
    fn get_peer_vat_id(&self) -> crate::rpc_twoparty_capnp::Side {
        self.inner.borrow().side
    }

    fn new_outgoing_message(&mut self, _first_segment_word_size: u32) -> Box<dyn crate::OutgoingMessage> {
        Box::new(OutgoingMessage {
            message: ::capnp::message::Builder::new_default(),
            sender: self.inner.borrow().sender.clone(),
        })
    }

    fn receive_incoming_message(&mut self) -> Promise<Option<Box<dyn crate::IncomingMessage + 'static>>, ::capnp::Error> {
        let mut inner = self.inner.borrow_mut();
        let maybe_input_stream = ::std::mem::replace(&mut *inner.input_stream.borrow_mut(), None);
        let return_it_here = inner.input_stream.clone();
        match maybe_input_stream {
            Some(mut s) => {
                let receive_options = inner.receive_options;
                Promise::from_future(async move {
                    let maybe_message = ::capnp_futures::serialize::read_message(&mut s, receive_options).await?;
                    *return_it_here.borrow_mut() = Some(s);
                    Ok(maybe_message.map(|message|
                                         Box::new(IncomingMessage::new(message)) as Box<dyn crate::IncomingMessage>))
                })
            }
            None => {
                Promise::err(::capnp::Error::failed("this should not be possible".to_string()))
             //   unreachable!(),
            }
        }
    }

    fn shutdown(&mut self, result: ::capnp::Result<()>) -> Promise<(), ::capnp::Error> {
        Promise::from_future(self.inner.borrow_mut().sender.terminate(result).map_err(|e| e.into()))
    }
}

/// A vat networks with two parties, the client and the server.
pub struct VatNetwork<T> where T: AsyncRead + 'static + Unpin {
    connection: Option<Connection<T>>,

    // HACK
    weak_connection_inner: Weak<RefCell<ConnectionInner<T>>>,

    execution_driver: futures::future::Shared<Promise<(), ::capnp::Error>>,
    side: crate::rpc_twoparty_capnp::Side,
}

impl <T> VatNetwork<T> where T: AsyncRead + Unpin {
    /// Creates a new two-party vat network that will receive data on `input_stream` and send data on
    /// `output_stream`.
    ///
    /// `side` indicates whether this is the client or the server side of the connection. This has no
    /// effect on the data sent over the connection; it merely exists so that `RpcNetwork::bootstrap` knows
    /// whether to return the local or the remote bootstrap capability. `VatId` parameters like this one
    /// will make more sense once we have vat networks with more than two parties.
    ///
    /// The options in `receive_options` will be used when reading the messages that come in on `input_stream`.
    pub fn new<U>(input_stream: T,
               output_stream: U,
               side: crate::rpc_twoparty_capnp::Side,
               receive_options: ReaderOptions) -> VatNetwork<T>
        where U: AsyncWrite + 'static + Unpin,
    {

        let (fulfiller, disconnect_promise) = oneshot::channel();
        let disconnect_promise = disconnect_promise
            .map_err(|_| ::capnp::Error::disconnected("disconnected".into()));

        let (execution_driver, sender) = {
            let (tx, write_queue) = ::capnp_futures::write_queue(output_stream);

            // Don't use `.join()` here because we need to make sure to wait for `disconnect_promise` to
            // resolve even if `write_queue` resolves to an error.
            (Promise::from_future(
                write_queue
                    .then(move |r| disconnect_promise.then(move |_| futures::future::ready(r)).map_ok(|_| ()))).shared(),
             tx)
        };

        let connection = Connection::new(input_stream, sender, side, receive_options, fulfiller);
        let weak_inner = Rc::downgrade(&connection.inner);
        VatNetwork {
            connection: Some(connection),
            weak_connection_inner: weak_inner,
            execution_driver: execution_driver,
            side: side,
        }
    }
}

impl <T> crate::VatNetwork<VatId> for VatNetwork<T>
    where T: AsyncRead + Unpin
{
    fn connect(&mut self, host_id: VatId) -> Option<Box<dyn crate::Connection<VatId>>> {
        if host_id == self.side {
            None
        } else {
            let connection = ::std::mem::replace(&mut self.connection, None);
            match connection {
                Some(c) => {
                    Some(Box::new(c))
                } None => {
                    match self.weak_connection_inner.upgrade() {
                        Some(connection_inner) => {
                            Some(Box::new(Connection { inner: connection_inner }))
                        }
                        None => {
                            panic!("tried to reconnect a disconnected twoparty vat network.")
                        }
                    }
                }
            }
        }
    }

    fn accept(&mut self) -> Promise<Box<dyn crate::Connection<VatId>>, ::capnp::Error> {
        let connection = ::std::mem::replace(&mut self.connection, None);
        match connection {
            Some(c) => Promise::ok(Box::new(c) as Box<dyn crate::Connection<VatId>>),
            None => Promise::from_future(::futures::future::pending()),
        }
    }

    fn drive_until_shutdown(&mut self) -> Promise<(), ::capnp::Error> {
        Promise::from_future(self.execution_driver.clone())
    }
}
<|endoftext|>