<commit_before>
use vm;

struct qemudbg {}

impl vm::io_handler_ops for qemudbg {
    fn io_read(&self, port: u16, size: u8) -> vm::IoOperandType {
        assert!(size == 1);
        assert!(port == 0x402);
        unimplemented!();
    }

    fn io_write(&mut self, addr: u16, data: vm::IoOperandType) {
        assert!(addr == 0x402);

        // Output to debug console
        debug!("{}", data.unwrap_byte() as char);
    }
}

pub fn init(vm: &mut vm::vm) {
    let dev = Box::new(qemudbg {});
    vm::register_io_handler(vm, dev, 0x402, 1);
}
<commit_msg>qemudbg will now write to separate file: qemudbg.out<commit_after>/*
 * qemudbg
 * Implementation of a qemu debug IO port device
 */

use vm;
use std::fs::*;
use std::io::Write;

const QEMUDBG_OUTPUT_FILE: &'static str = "qemudbg.out";

struct qemudbg {
    file: File,
}

impl vm::io_handler_ops for qemudbg {
    fn io_read(&self, port: u16, size: u8) -> vm::IoOperandType {
        assert!(size == 1);
        assert!(port == 0x402);
        unimplemented!();
    }

    fn io_write(&mut self, addr: u16, data: vm::IoOperandType) {
        assert!(addr == 0x402);

        let c: char = data.unwrap_byte() as char;

        self.file.write_fmt(format_args!("{}", c)).unwrap_or_else(|err| {
            error!("qemudbg: failed writing to file: {}", err);
        });

        // Output to debug console as well
        debug!("{}", data.unwrap_byte() as char);
    }
}

pub fn init(vm: &mut vm::vm)
{
    let dev = Box::new(qemudbg {
        file: File::create(QEMUDBG_OUTPUT_FILE).unwrap(),
    });

    vm::register_io_handler(vm, dev, 0x402, 1);
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use texturegl::Texture;

use geom::matrix::{Matrix4, identity};
use geom::size::Size2D;
use geom::rect::Rect;
use std::cell::RefCell;
use std::rc::Rc;

pub enum Format {
    ARGB32Format,
    RGB24Format
}

#[deriving(Clone)]
pub enum Layer {
    ContainerLayerKind(Rc<ContainerLayer>),
    TextureLayerKind(Rc<TextureLayer>),
}

impl Layer {
    pub fn with_common<T>(&self, f: |&mut CommonLayer| -> T) -> T {
        match *self {
            ContainerLayerKind(ref container_layer) => {
                let mut tmp = container_layer.borrow().common.borrow_mut();
                f(tmp.get())
            },
            TextureLayerKind(ref texture_layer) => {
                let mut tmp = texture_layer.borrow().common.borrow_mut();
                f(tmp.get())
            },
        }
    }
}

pub struct CommonLayer {
    parent: Option<Layer>,
    prev_sibling: Option<Layer>,
    next_sibling: Option<Layer>,

    transform: Matrix4<f32>,
}

impl CommonLayer {
    // FIXME: Workaround for cross-crate bug regarding mutability of class fields
    pub fn set_transform(&mut self, new_transform: Matrix4<f32>) {
        self.transform = new_transform;
    }
}

pub fn CommonLayer() -> CommonLayer {
    CommonLayer {
        parent: None,
        prev_sibling: None,
        next_sibling: None,
        transform: identity(),
    }
}

pub struct ContainerLayer {
    common: RefCell<CommonLayer>,
    first_child: RefCell<Option<Layer>>,
    last_child: RefCell<Option<Layer>>,
    scissor: RefCell<Option<Rect<f32>>>,
}

pub fn ContainerLayer() -> ContainerLayer {
    ContainerLayer {
        common: RefCell::new(CommonLayer()),
        first_child: RefCell::new(None),
        last_child: RefCell::new(None),
        scissor: RefCell::new(None),
    }
}

struct ChildIterator {
    current: Option<Layer>,
}

impl Iterator<Layer> for ChildIterator {
    fn next(&mut self) -> Option<Layer> {
        let (new_current, result) =
            match self.current {
                None => (None, None),
                Some(ref child) => {
                    (child.with_common(|x| x.next_sibling.clone()),
                     Some(child.clone()))
                }
            };
        self.current = new_current;
        result
    }
}

impl ContainerLayer {
    pub fn children(&self) -> ChildIterator {
        ChildIterator { current: {
                // NOTE: work around borrowchk
                let tmp = self.first_child.borrow();
                tmp.get().clone()
            }
        }
    }

    /// Adds a child to the beginning of the list.
    /// Only works when the child is disconnected from the layer tree.
    pub fn add_child_start(pseudo_self: Rc<ContainerLayer>, new_child: Layer) {
        new_child.with_common(|new_child_common| {
            assert!(new_child_common.parent.is_none());
            assert!(new_child_common.prev_sibling.is_none());
            assert!(new_child_common.next_sibling.is_none());

            new_child_common.parent = Some(ContainerLayerKind(pseudo_self.clone()));

            // NOTE: work around borrowchk
            {
                let tmp = pseudo_self.borrow().first_child.borrow();
                match *tmp.get() {
                    None => {}
                    Some(ref first_child) => {
                        first_child.with_common(|first_child_common| {
                            assert!(first_child_common.prev_sibling.is_none());
                            first_child_common.prev_sibling = Some(new_child.clone());
                            new_child_common.next_sibling = Some(first_child.clone());
                        });
                    }
                }
            }

            pseudo_self.borrow().first_child.set(Some(new_child.clone()));

            match pseudo_self.borrow().last_child.borrow().get() {
                &None => pseudo_self.borrow().last_child.set(Some(new_child.clone())),
                &Some(_) => {}
            }
        });
    }

    /// Adds a child to the end of the list.
    /// Only works when the child is disconnected from the layer tree.
    pub fn add_child_end(pseudo_self: Rc<ContainerLayer>, new_child: Layer) {
        new_child.with_common(|new_child_common| {
            assert!(new_child_common.parent.is_none());
            assert!(new_child_common.prev_sibling.is_none());
            assert!(new_child_common.next_sibling.is_none());

            new_child_common.parent = Some(ContainerLayerKind(pseudo_self.clone()));

            // NOTE: work around borrowchk
            {
                let tmp = pseudo_self.borrow().last_child.borrow();
                match *tmp.get() {
                    None => {}
                    Some(ref last_child) => {
                        last_child.with_common(|last_child_common| {
                            assert!(last_child_common.next_sibling.is_none());
                            last_child_common.next_sibling = Some(new_child.clone());
                            new_child_common.prev_sibling = Some(last_child.clone());
                        });
                    }
                }
            }

            pseudo_self.borrow().last_child.set(Some(new_child.clone()));

            pseudo_self.borrow().first_child.with_mut(|child|
                                                      match *child {
                                                          Some(_) => {},
                                                          None => *child = Some(new_child.clone()),
                                                      });
        });
    }

    pub fn remove_child(pseudo_self: Rc<ContainerLayer>, child: Layer) {
        child.with_common(|child_common| {
            assert!(child_common.parent.is_some());
            match child_common.parent {
                Some(ContainerLayerKind(ref container)) => {
                    assert!(container.borrow() as *ContainerLayer ==
                            pseudo_self.borrow() as *ContainerLayer);
                },
                _ => fail!(~"Invalid parent of child in layer tree"),
            }

            match child_common.next_sibling {
                None => { // this is the last child
                    pseudo_self.borrow().last_child.set(child_common.prev_sibling.clone());
                },
                Some(ref sibling) => {
                    sibling.with_common(|sibling_common| {
                        sibling_common.prev_sibling = child_common.prev_sibling.clone();
                    });
                }
            }
            match child_common.prev_sibling {
                None => { // this is the first child
                    pseudo_self.borrow().first_child.set(child_common.next_sibling.clone());
                },
                Some(ref sibling) => {
                    sibling.with_common(|sibling_common| {
                        sibling_common.next_sibling = child_common.next_sibling.clone();
                    });
                }
            }
        });
    }
}

/// Whether a texture should be flipped.
#[deriving(Eq)]
pub enum Flip {
    /// The texture should not be flipped.
    NoFlip,
    /// The texture should be flipped vertically.
    VerticalFlip,
}

pub struct TextureLayer {
    common: RefCell<CommonLayer>,
    /// A handle to the GPU texture.
    texture: Texture,
    /// The size of the texture in pixels.
    size: Size2D<uint>,
    /// Whether this texture is flipped vertically.
    flip: Flip,
}

impl TextureLayer {
    pub fn new(texture: Texture, size: Size2D<uint>, flip: Flip) -> TextureLayer {
        TextureLayer {
            common: RefCell::new(CommonLayer()),
            texture: texture,
            size: size,
            flip: flip,
        }
    }
}

<commit_msg>Fix double-borrow failure<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use texturegl::Texture;

use geom::matrix::{Matrix4, identity};
use geom::size::Size2D;
use geom::rect::Rect;
use std::cell::RefCell;
use std::rc::Rc;

pub enum Format {
    ARGB32Format,
    RGB24Format
}

#[deriving(Clone)]
pub enum Layer {
    ContainerLayerKind(Rc<ContainerLayer>),
    TextureLayerKind(Rc<TextureLayer>),
}

impl Layer {
    pub fn with_common<T>(&self, f: |&mut CommonLayer| -> T) -> T {
        match *self {
            ContainerLayerKind(ref container_layer) => {
                let mut tmp = container_layer.borrow().common.borrow_mut();
                f(tmp.get())
            },
            TextureLayerKind(ref texture_layer) => {
                let mut tmp = texture_layer.borrow().common.borrow_mut();
                f(tmp.get())
            },
        }
    }
}

pub struct CommonLayer {
    parent: Option<Layer>,
    prev_sibling: Option<Layer>,
    next_sibling: Option<Layer>,

    transform: Matrix4<f32>,
}

impl CommonLayer {
    // FIXME: Workaround for cross-crate bug regarding mutability of class fields
    pub fn set_transform(&mut self, new_transform: Matrix4<f32>) {
        self.transform = new_transform;
    }
}

pub fn CommonLayer() -> CommonLayer {
    CommonLayer {
        parent: None,
        prev_sibling: None,
        next_sibling: None,
        transform: identity(),
    }
}

pub struct ContainerLayer {
    common: RefCell<CommonLayer>,
    first_child: RefCell<Option<Layer>>,
    last_child: RefCell<Option<Layer>>,
    scissor: RefCell<Option<Rect<f32>>>,
}

pub fn ContainerLayer() -> ContainerLayer {
    ContainerLayer {
        common: RefCell::new(CommonLayer()),
        first_child: RefCell::new(None),
        last_child: RefCell::new(None),
        scissor: RefCell::new(None),
    }
}

struct ChildIterator {
    current: Option<Layer>,
}

impl Iterator<Layer> for ChildIterator {
    fn next(&mut self) -> Option<Layer> {
        let (new_current, result) =
            match self.current {
                None => (None, None),
                Some(ref child) => {
                    (child.with_common(|x| x.next_sibling.clone()),
                     Some(child.clone()))
                }
            };
        self.current = new_current;
        result
    }
}

impl ContainerLayer {
    pub fn children(&self) -> ChildIterator {
        ChildIterator { current: {
                // NOTE: work around borrowchk
                let tmp = self.first_child.borrow();
                tmp.get().clone()
            }
        }
    }

    /// Adds a child to the beginning of the list.
    /// Only works when the child is disconnected from the layer tree.
    pub fn add_child_start(pseudo_self: Rc<ContainerLayer>, new_child: Layer) {
        new_child.with_common(|new_child_common| {
            assert!(new_child_common.parent.is_none());
            assert!(new_child_common.prev_sibling.is_none());
            assert!(new_child_common.next_sibling.is_none());

            new_child_common.parent = Some(ContainerLayerKind(pseudo_self.clone()));

            // NOTE: work around borrowchk
            {
                let tmp = pseudo_self.borrow().first_child.borrow();
                match *tmp.get() {
                    None => {}
                    Some(ref first_child) => {
                        first_child.with_common(|first_child_common| {
                            assert!(first_child_common.prev_sibling.is_none());
                            first_child_common.prev_sibling = Some(new_child.clone());
                            new_child_common.next_sibling = Some(first_child.clone());
                        });
                    }
                }
            }

            pseudo_self.borrow().first_child.set(Some(new_child.clone()));

            let should_set = pseudo_self.borrow().last_child.borrow().get().is_none();
            if should_set {
                pseudo_self.borrow().last_child.set(Some(new_child.clone()));
            }
        });
    }

    /// Adds a child to the end of the list.
    /// Only works when the child is disconnected from the layer tree.
    pub fn add_child_end(pseudo_self: Rc<ContainerLayer>, new_child: Layer) {
        new_child.with_common(|new_child_common| {
            assert!(new_child_common.parent.is_none());
            assert!(new_child_common.prev_sibling.is_none());
            assert!(new_child_common.next_sibling.is_none());

            new_child_common.parent = Some(ContainerLayerKind(pseudo_self.clone()));

            // NOTE: work around borrowchk
            {
                let tmp = pseudo_self.borrow().last_child.borrow();
                match *tmp.get() {
                    None => {}
                    Some(ref last_child) => {
                        last_child.with_common(|last_child_common| {
                            assert!(last_child_common.next_sibling.is_none());
                            last_child_common.next_sibling = Some(new_child.clone());
                            new_child_common.prev_sibling = Some(last_child.clone());
                        });
                    }
                }
            }

            pseudo_self.borrow().last_child.set(Some(new_child.clone()));

            pseudo_self.borrow().first_child.with_mut(|child|
                                                      match *child {
                                                          Some(_) => {},
                                                          None => *child = Some(new_child.clone()),
                                                      });
        });
    }

    pub fn remove_child(pseudo_self: Rc<ContainerLayer>, child: Layer) {
        child.with_common(|child_common| {
            assert!(child_common.parent.is_some());
            match child_common.parent {
                Some(ContainerLayerKind(ref container)) => {
                    assert!(container.borrow() as *ContainerLayer ==
                            pseudo_self.borrow() as *ContainerLayer);
                },
                _ => fail!(~"Invalid parent of child in layer tree"),
            }

            match child_common.next_sibling {
                None => { // this is the last child
                    pseudo_self.borrow().last_child.set(child_common.prev_sibling.clone());
                },
                Some(ref sibling) => {
                    sibling.with_common(|sibling_common| {
                        sibling_common.prev_sibling = child_common.prev_sibling.clone();
                    });
                }
            }
            match child_common.prev_sibling {
                None => { // this is the first child
                    pseudo_self.borrow().first_child.set(child_common.next_sibling.clone());
                },
                Some(ref sibling) => {
                    sibling.with_common(|sibling_common| {
                        sibling_common.next_sibling = child_common.next_sibling.clone();
                    });
                }
            }
        });
    }
}

/// Whether a texture should be flipped.
#[deriving(Eq)]
pub enum Flip {
    /// The texture should not be flipped.
    NoFlip,
    /// The texture should be flipped vertically.
    VerticalFlip,
}

pub struct TextureLayer {
    common: RefCell<CommonLayer>,
    /// A handle to the GPU texture.
    texture: Texture,
    /// The size of the texture in pixels.
    size: Size2D<uint>,
    /// Whether this texture is flipped vertically.
    flip: Flip,
}

impl TextureLayer {
    pub fn new(texture: Texture, size: Size2D<uint>, flip: Flip) -> TextureLayer {
        TextureLayer {
            common: RefCell::new(CommonLayer()),
            texture: texture,
            size: size,
            flip: flip,
        }
    }
}

<|endoftext|>


<commit_before>extern crate ra_syntax;
extern crate superslice;
extern crate itertools;
extern crate join_to_string;
#[cfg(test)]
#[macro_use]
extern crate test_utils as _test_utils;

mod extend_selection;
mod symbols;
mod line_index;
mod edit;
mod folding_ranges;
mod code_actions;
mod typing;
mod completion;
mod scope;
#[cfg(test)]
mod test_utils;

use ra_syntax::{
    File, TextUnit, TextRange, SmolStr, SyntaxNodeRef,
    ast::{self, AstNode, NameOwner},
    algo::find_leaf_at_offset,
    SyntaxKind::{self, *},
};
pub use ra_syntax::AtomEdit;
pub use self::{
    line_index::{LineIndex, LineCol},
    extend_selection::extend_selection,
    symbols::{StructureNode, file_structure, FileSymbol, file_symbols},
    edit::{EditBuilder, Edit},
    code_actions::{
        LocalEdit,
        flip_comma, add_derive, add_impl,
        introduce_variable,
    },
    typing::{join_lines, on_eq_typed, on_enter},
    completion::{scope_completion, CompletionItem},
    folding_ranges::{Fold, FoldKind, folding_ranges}
};

#[derive(Debug)]
pub struct HighlightedRange {
    pub range: TextRange,
    pub tag: &'static str,
}

#[derive(Debug)]
pub struct Diagnostic {
    pub range: TextRange,
    pub msg: String,
}

#[derive(Debug)]
pub struct Runnable {
    pub range: TextRange,
    pub kind: RunnableKind,
}

#[derive(Debug)]
pub enum RunnableKind {
    Test { name: String },
    Bin,
}

pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> {
    const BRACES: &[SyntaxKind] = &[
        L_CURLY, R_CURLY,
        L_BRACK, R_BRACK,
        L_PAREN, R_PAREN,
        L_ANGLE, R_ANGLE,
    ];
    let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset)
        .filter_map(|node| {
            let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
            Some((node, idx))
        })
        .next()?;
    let parent = brace_node.parent()?;
    let matching_kind = BRACES[brace_idx ^ 1];
    let matching_node = parent.children()
        .find(|node| node.kind() == matching_kind)?;
    Some(matching_node.range().start())
}

pub fn highlight(file: &File) -> Vec<HighlightedRange> {
    let mut res = Vec::new();
    for node in file.syntax().descendants() {
        let tag = match node.kind() {
            COMMENT | DOC_COMMENT => "comment",
            STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
            ATTR => "attribute",
            NAME_REF => "text",
            NAME => "function",
            INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal",
            LIFETIME => "parameter",
            k if k.is_keyword() => "keyword",
            _ => continue,
        };
        res.push(HighlightedRange {
            range: node.range(),
            tag,
        })
    }
    res
}

pub fn diagnostics(file: &File) -> Vec<Diagnostic> {
    let mut res = Vec::new();

    for node in file.syntax().descendants() {
        if node.kind() == ERROR {
            res.push(Diagnostic {
                range: node.range(),
                msg: "Syntax Error".to_string(),
            });
        }
    }
    res.extend(file.errors().into_iter().map(|err| Diagnostic {
        range: TextRange::offset_len(err.offset, 1.into()),
        msg: err.msg,
    }));
    res
}

pub fn syntax_tree(file: &File) -> String {
    ::ra_syntax::utils::dump_tree(file.syntax())
}

pub fn runnables(file: &File) -> Vec<Runnable> {
    file.syntax().descendants()
        .filter_map(ast::FnDef::cast)
        .filter_map(|f| {
            let name = f.name()?.text();
            let kind = if name == "main" {
                RunnableKind::Bin
            } else if f.has_atom_attr("test") {
                RunnableKind::Test {
                    name: name.to_string()
                }
            } else {
                return None;
            };
            Some(Runnable {
                range: f.syntax().range(),
                kind,
            })
        })
        .collect()
}

pub fn find_node_at_offset<'a, N: AstNode<'a>>(
    syntax: SyntaxNodeRef<'a>,
    offset: TextUnit,
) -> Option<N> {
    let leaves = find_leaf_at_offset(syntax, offset);
    let leaf = leaves.clone()
        .find(|leaf| !leaf.kind().is_trivia())
        .or_else(|| leaves.right_biased())?;
    leaf.ancestors()
        .filter_map(N::cast)
        .next()
}

pub fn resolve_local_name(file: &File, offset: TextUnit, name_ref: ast::NameRef) -> Option<(SmolStr, TextRange)> {
    let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), offset)?;
    let scopes = scope::FnScopes::new(fn_def);
    let scope_entry = scope::resolve_local_name(name_ref, &scopes)?;
    let name = scope_entry.ast().name()?;
    Some((scope_entry.name(), name.syntax().range()))
}

#[cfg(test)]
mod tests {
    use super::*;
    use test_utils::{assert_eq_dbg, extract_offset, add_cursor};

    #[test]
    fn test_highlighting() {
        let file = File::parse(r#"
// comment
fn main() {}
    println!("Hello, {}!", 92);
"#);
        let hls = highlight(&file);
        assert_eq_dbg(
            r#"[HighlightedRange { range: [1; 11), tag: "comment" },
                HighlightedRange { range: [12; 14), tag: "keyword" },
                HighlightedRange { range: [15; 19), tag: "function" },
                HighlightedRange { range: [29; 36), tag: "text" },
                HighlightedRange { range: [38; 50), tag: "string" },
                HighlightedRange { range: [52; 54), tag: "literal" }]"#,
            &hls,
        );
    }

    #[test]
    fn test_runnables() {
      let file = File::parse(r#"
fn main() {}

#[test]
fn test_foo() {}

#[test]
#[ignore]
fn test_foo() {}
"#);
        let runnables = runnables(&file);
        assert_eq_dbg(
            r#"[Runnable { range: [1; 13), kind: Bin },
                Runnable { range: [15; 39), kind: Test { name: "test_foo" } },
                Runnable { range: [41; 75), kind: Test { name: "test_foo" } }]"#,
            &runnables,
        )
    }

    #[test]
    fn test_matching_brace() {
        fn do_check(before: &str, after: &str) {
            let (pos, before) = extract_offset(before);
            let file = File::parse(&before);
            let new_pos = match matching_brace(&file, pos) {
                None => pos,
                Some(pos) => pos,
            };
            let actual = add_cursor(&before, new_pos);
            assert_eq_text!(after, &actual);
        }

        do_check(
            "struct Foo { a: i32, }<|>",
            "struct Foo <|>{ a: i32, }",
        );
    }
}
<commit_msg>Report errors only once<commit_after>extern crate ra_syntax;
extern crate superslice;
extern crate itertools;
extern crate join_to_string;
#[cfg(test)]
#[macro_use]
extern crate test_utils as _test_utils;

mod extend_selection;
mod symbols;
mod line_index;
mod edit;
mod folding_ranges;
mod code_actions;
mod typing;
mod completion;
mod scope;
#[cfg(test)]
mod test_utils;

use ra_syntax::{
    File, TextUnit, TextRange, SmolStr, SyntaxNodeRef,
    ast::{self, AstNode, NameOwner},
    algo::find_leaf_at_offset,
    SyntaxKind::{self, *},
};
pub use ra_syntax::AtomEdit;
pub use self::{
    line_index::{LineIndex, LineCol},
    extend_selection::extend_selection,
    symbols::{StructureNode, file_structure, FileSymbol, file_symbols},
    edit::{EditBuilder, Edit},
    code_actions::{
        LocalEdit,
        flip_comma, add_derive, add_impl,
        introduce_variable,
    },
    typing::{join_lines, on_eq_typed, on_enter},
    completion::{scope_completion, CompletionItem},
    folding_ranges::{Fold, FoldKind, folding_ranges}
};

#[derive(Debug)]
pub struct HighlightedRange {
    pub range: TextRange,
    pub tag: &'static str,
}

#[derive(Debug)]
pub struct Diagnostic {
    pub range: TextRange,
    pub msg: String,
}

#[derive(Debug)]
pub struct Runnable {
    pub range: TextRange,
    pub kind: RunnableKind,
}

#[derive(Debug)]
pub enum RunnableKind {
    Test { name: String },
    Bin,
}

pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> {
    const BRACES: &[SyntaxKind] = &[
        L_CURLY, R_CURLY,
        L_BRACK, R_BRACK,
        L_PAREN, R_PAREN,
        L_ANGLE, R_ANGLE,
    ];
    let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset)
        .filter_map(|node| {
            let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
            Some((node, idx))
        })
        .next()?;
    let parent = brace_node.parent()?;
    let matching_kind = BRACES[brace_idx ^ 1];
    let matching_node = parent.children()
        .find(|node| node.kind() == matching_kind)?;
    Some(matching_node.range().start())
}

pub fn highlight(file: &File) -> Vec<HighlightedRange> {
    let mut res = Vec::new();
    for node in file.syntax().descendants() {
        let tag = match node.kind() {
            COMMENT | DOC_COMMENT => "comment",
            STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
            ATTR => "attribute",
            NAME_REF => "text",
            NAME => "function",
            INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal",
            LIFETIME => "parameter",
            k if k.is_keyword() => "keyword",
            _ => continue,
        };
        res.push(HighlightedRange {
            range: node.range(),
            tag,
        })
    }
    res
}

pub fn diagnostics(file: &File) -> Vec<Diagnostic> {
    file.errors().into_iter().map(|err| Diagnostic {
        range: TextRange::offset_len(err.offset, 1.into()),
        msg: "Syntax Error: ".to_string() + &err.msg,
    }).collect()
}

pub fn syntax_tree(file: &File) -> String {
    ::ra_syntax::utils::dump_tree(file.syntax())
}

pub fn runnables(file: &File) -> Vec<Runnable> {
    file.syntax().descendants()
        .filter_map(ast::FnDef::cast)
        .filter_map(|f| {
            let name = f.name()?.text();
            let kind = if name == "main" {
                RunnableKind::Bin
            } else if f.has_atom_attr("test") {
                RunnableKind::Test {
                    name: name.to_string()
                }
            } else {
                return None;
            };
            Some(Runnable {
                range: f.syntax().range(),
                kind,
            })
        })
        .collect()
}

pub fn find_node_at_offset<'a, N: AstNode<'a>>(
    syntax: SyntaxNodeRef<'a>,
    offset: TextUnit,
) -> Option<N> {
    let leaves = find_leaf_at_offset(syntax, offset);
    let leaf = leaves.clone()
        .find(|leaf| !leaf.kind().is_trivia())
        .or_else(|| leaves.right_biased())?;
    leaf.ancestors()
        .filter_map(N::cast)
        .next()
}

pub fn resolve_local_name(file: &File, offset: TextUnit, name_ref: ast::NameRef) -> Option<(SmolStr, TextRange)> {
    let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), offset)?;
    let scopes = scope::FnScopes::new(fn_def);
    let scope_entry = scope::resolve_local_name(name_ref, &scopes)?;
    let name = scope_entry.ast().name()?;
    Some((scope_entry.name(), name.syntax().range()))
}

#[cfg(test)]
mod tests {
    use super::*;
    use test_utils::{assert_eq_dbg, extract_offset, add_cursor};

    #[test]
    fn test_highlighting() {
        let file = File::parse(r#"
// comment
fn main() {}
    println!("Hello, {}!", 92);
"#);
        let hls = highlight(&file);
        assert_eq_dbg(
            r#"[HighlightedRange { range: [1; 11), tag: "comment" },
                HighlightedRange { range: [12; 14), tag: "keyword" },
                HighlightedRange { range: [15; 19), tag: "function" },
                HighlightedRange { range: [29; 36), tag: "text" },
                HighlightedRange { range: [38; 50), tag: "string" },
                HighlightedRange { range: [52; 54), tag: "literal" }]"#,
            &hls,
        );
    }

    #[test]
    fn test_runnables() {
      let file = File::parse(r#"
fn main() {}

#[test]
fn test_foo() {}

#[test]
#[ignore]
fn test_foo() {}
"#);
        let runnables = runnables(&file);
        assert_eq_dbg(
            r#"[Runnable { range: [1; 13), kind: Bin },
                Runnable { range: [15; 39), kind: Test { name: "test_foo" } },
                Runnable { range: [41; 75), kind: Test { name: "test_foo" } }]"#,
            &runnables,
        )
    }

    #[test]
    fn test_matching_brace() {
        fn do_check(before: &str, after: &str) {
            let (pos, before) = extract_offset(before);
            let file = File::parse(&before);
            let new_pos = match matching_brace(&file, pos) {
                None => pos,
                Some(pos) => pos,
            };
            let actual = add_cursor(&before, new_pos);
            assert_eq_text!(after, &actual);
        }

        do_check(
            "struct Foo { a: i32, }<|>",
            "struct Foo <|>{ a: i32, }",
        );
    }
}
<|endoftext|>


<commit_before>use url::{Url};

use std::fmt::{Show, Formatter, FormatError};
use std::io::net::ip::SocketAddr;
use http::headers::request::HeaderCollection;
use http::server::request::{AbsoluteUri, AbsolutePath};
use http::method::Method;
use http::server::request::Request as HttpRequest;

pub struct Request {

	pub url: Url,
	pub remote_addr: Option<SocketAddr>,
    pub headers: HeaderCollection,
    pub body: String,
    pub method: Method

}

impl Show for Request {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        try!(writeln!(f, "Request ->"));
        try!(writeln!(f, "	url: {}", self.url));
        try!(writeln!(f, "	method: {}", self.method));
        try!(writeln!(f, "	path: {}", self.url.path()));
        try!(writeln!(f, "	query: {}", self.url.query));
        try!(writeln!(f, "	remote_addr: {}", self.remote_addr));
        try!(writeln!(f, "	body: {}", self.body));
        Ok(())
    }
}

impl Request {
	pub fn wrap(req: HttpRequest) -> Result<Request, String> {
		match req.request_uri {

			AbsoluteUri(url) => {
				let string_url: String = format!("{}", url);
				let parsed_url: Url = match Url::parse(string_url.as_slice()) {
					Ok(Url) => Url,
					Err(parse_error) => return Err(format!("{}", parse_error))
				};

				Ok(Request {
					url: parsed_url,
					remote_addr: req.remote_addr,
					headers: req.headers,
					body: req.body,
					method: req.method
				})
			},

			AbsolutePath(path) => {

				let url_string = match req.headers.host {
                    Some(ref host) => format!("http://{}{}", host, path),
                    None => return Err("No HOST header specified in request".to_string())
                };

				let parsed_url: Url = match Url::parse(url_string.as_slice()) {
					Ok(url) => url,
					Err(parse_error) => return Err(format!("{}", parse_error))
				};

				Ok(Request {
					url: parsed_url,
					remote_addr: req.remote_addr,
					headers: req.headers,
					body: req.body,
					method: req.method
				})

			},

			_ => Err("Unsupported request URI".to_string())

		}
	}
}<commit_msg>feat: DRY Request<commit_after>use url::{Url};

use std::fmt::{Show, Formatter, FormatError};
use std::io::net::ip::SocketAddr;
use http::headers::request::HeaderCollection;
use http::server::request::{AbsoluteUri, AbsolutePath};
use http::method::Method;
use http::server::request::Request as HttpRequest;

pub struct Request {
	pub url: Url,
	pub remote_addr: Option<SocketAddr>,
    pub headers: HeaderCollection,
    pub body: String,
    pub method: Method
}

impl Show for Request {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        try!(writeln!(f, "Request ->"));
        try!(writeln!(f, "	url: {}", self.url));
        try!(writeln!(f, "	method: {}", self.method));
        try!(writeln!(f, "	path: {}", self.url.path()));
        try!(writeln!(f, "	query: {}", self.url.query));
        try!(writeln!(f, "	remote_addr: {}", self.remote_addr));
        try!(writeln!(f, "	body: {}", self.body));
        Ok(())
    }
}

impl Request {
	pub fn wrap(req: HttpRequest) -> Result<Request, String> {

		let url = match req.request_uri {

			AbsoluteUri(url) => format!("{}", url),
			AbsolutePath(path) => {
				match req.headers.host {
                    Some(ref host) => format!("http://{}{}", host, path),
                    None => return Err("No HOST header specified in request".to_string())
                }
			},

			_ => return Err("Unsupported request URI".to_string())

		};

		let parsed_url = match Url::parse(url.as_slice()) {
			Ok(url) => url,
			Err(parse_error) => return Err(format!("{}", parse_error))
		};

		Ok(Request {
			url: parsed_url,
			remote_addr: req.remote_addr,
			headers: req.headers,
			body: req.body,
			method: req.method
		})

	}
}<|endoftext|>


<commit_before>// Copyright 2015-2019 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use std::cmp::Ordering;
use std::fmt::{self, Debug, Formatter};
use std::pin::Pin;
use std::sync::Arc;
use std::time::Instant;

use futures::{lock::Mutex, Future};
#[cfg(feature = "tokio-runtime")]
use tokio::runtime::Handle;

use proto::error::{ProtoError, ProtoResult};
#[cfg(feature = "mdns")]
use proto::multicast::MDNS_IPV4;
use proto::op::ResponseCode;
use proto::xfer::{DnsHandle, DnsRequest, DnsResponse};

#[cfg(feature = "mdns")]
use crate::config::Protocol;
use crate::config::{NameServerConfig, ResolverOpts};
use crate::name_server::{ConnectionProvider, NameServerState, NameServerStats};
#[cfg(feature = "tokio-runtime")]
use crate::name_server::{TokioConnection, TokioConnectionProvider};

/// Specifies the details of a remote NameServer used for lookups
#[derive(Clone)]
pub struct NameServer<C: DnsHandle + Send, P: ConnectionProvider<Conn = C> + Send> {
    config: NameServerConfig,
    options: ResolverOpts,
    client: Arc<Mutex<Option<C>>>,
    state: Arc<NameServerState>,
    stats: Arc<NameServerStats>,
    conn_provider: P,
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> Debug for NameServer<C, P> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "config: {:?}, options: {:?}", self.config, self.options)
    }
}

#[cfg(feature = "tokio-runtime")]
impl NameServer<TokioConnection, TokioConnectionProvider> {
    pub fn new(config: NameServerConfig, options: ResolverOpts, runtime: Handle) -> Self {
        Self::new_with_provider(config, options, TokioConnectionProvider::new(runtime))
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> NameServer<C, P> {
    pub fn new_with_provider(
        config: NameServerConfig,
        options: ResolverOpts,
        conn_provider: P,
    ) -> NameServer<C, P> {
        Self {
            config,
            options,
            client: Arc::new(Mutex::new(None)),
            state: Arc::new(NameServerState::init(None)),
            stats: Arc::new(NameServerStats::default()),
            conn_provider,
        }
    }

    #[doc(hidden)]
    pub fn from_conn(
        config: NameServerConfig,
        options: ResolverOpts,
        client: C,
        conn_provider: P,
    ) -> NameServer<C, P> {
        Self {
            config,
            options,
            client: Arc::new(Mutex::new(Some(client))),
            state: Arc::new(NameServerState::init(None)),
            stats: Arc::new(NameServerStats::default()),
            conn_provider,
        }
    }

    #[cfg(test)]
    pub(crate) fn is_connected(&self) -> bool {
        !self.state.is_failed()
            && if let Some(client) = self.client.try_lock() {
                client.is_some()
            } else {
                // assuming that if someone has it locked it will be or is connected
                true
            }
    }

    /// This will return a mutable client to allows for sending messages.
    ///
    /// If the connection is in a failed state, then this will establish a new connection
    async fn connected_mut_client(&mut self) -> ProtoResult<C> {
        let mut client = self.client.lock().await;

        // if this is in a failure state
        if self.state.is_failed() || client.is_none() {
            debug!("reconnecting: {:?}", self.config);

            // TODO: we need the local EDNS options
            self.state.reinit(None);

            let new_client = self
                .conn_provider
                .new_connection(&self.config, &self.options)
                .await?;

            // establish a new connection
            *client = Some(new_client);
        } else {
            debug!("existing connection: {:?}", self.config);
        }

        Ok((*client)
            .clone()
            .expect("bad state, client should be connected"))
    }

    async fn inner_send<R: Into<DnsRequest> + Unpin + Send + 'static>(
        mut self,
        request: R,
    ) -> Result<DnsResponse, ProtoError> {
        let mut client = self.connected_mut_client().await?;
        let response = client.send(request).await;

        match response {
            Ok(response) => {
                // first we'll evaluate if the message succeeded
                //   see https://github.com/bluejekyll/trust-dns/issues/606
                //   TODO: there are probably other return codes from the server we may want to
                //    retry on. We may also want to evaluate NoError responses that lack records as errors as well
                if self.options.distrust_nx_responses {
                    if let ResponseCode::ServFail = response.response_code() {
                        let note = "Nameserver responded with SERVFAIL";
                        debug!("{}", note);
                        return Err(ProtoError::from(note));
                    }
                }

                // TODO: consider making message::take_edns...
                let remote_edns = response.edns().cloned();

                // take the remote edns options and store them
                self.state.establish(remote_edns);

                // record the success
                self.stats.next_success();
                Ok(response)
            }
            Err(error) => {
                debug!("name_server connection failure: {}", error);

                // this transitions the state to failure
                self.state.fail(Instant::now());

                // record the failure
                self.stats.next_failure();

                // These are connection failures, not lookup failures, that is handled in the resolver layer
                Err(error)
            }
        }
    }
}

impl<C, P> DnsHandle for NameServer<C, P>
where
    C: DnsHandle,
    P: ConnectionProvider<Conn = C>,
{
    type Response = Pin<Box<dyn Future<Output = Result<DnsResponse, ProtoError>> + Send>>;

    fn is_verifying_dnssec(&self) -> bool {
        self.options.validate
    }

    // TODO: there needs to be some way of customizing the connection based on EDNS options from the server side...
    fn send<R: Into<DnsRequest> + Unpin + Send + 'static>(&mut self, request: R) -> Self::Response {
        let this = self.clone();
        // if state is failed, return future::err(), unless retry delay expired..
        Box::pin(this.inner_send(request))
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> Ord for NameServer<C, P> {
    /// Custom implementation of Ord for NameServer which incorporates the performance of the connection into it's ranking
    fn cmp(&self, other: &Self) -> Ordering {
        // if they are literally equal, just return
        if self == other {
            return Ordering::Equal;
        }

        // otherwise, run our evaluation to determine the next to be returned from the Heap
        //   this will prefer established connections, we should try other connections after
        //   some number to make sure that all are used. This is more important for when
        //   latency is started to be used.
        match self.state.cmp(&other.state) {
            Ordering::Equal => (),
            o => {
                return o;
            }
        }

        self.stats.cmp(&other.stats)
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> PartialOrd for NameServer<C, P> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> PartialEq for NameServer<C, P> {
    /// NameServers are equal if the config (connection information) are equal
    fn eq(&self, other: &Self) -> bool {
        self.config == other.config
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> Eq for NameServer<C, P> {}

// TODO: once IPv6 is better understood, also make this a binary keep.
#[cfg(feature = "mdns")]
pub(crate) fn mdns_nameserver<C, P>(options: ResolverOpts, conn_provider: P) -> NameServer<C, P>
where
    C: DnsHandle,
    P: ConnectionProvider<Conn = C>,
{
    let config = NameServerConfig {
        socket_addr: *MDNS_IPV4,
        protocol: Protocol::Mdns,
        tls_dns_name: None,
        #[cfg(feature = "dns-over-rustls")]
        tls_config: None,
    };
    NameServer::new_with_provider(config, options, conn_provider)
}

#[cfg(test)]
#[cfg(feature = "tokio-runtime")]
mod tests {
    extern crate env_logger;

    use std::net::{IpAddr, Ipv4Addr, SocketAddr};
    use std::time::Duration;

    use futures::{future, FutureExt};
    use tokio::runtime::Runtime;

    use proto::op::{Query, ResponseCode};
    use proto::rr::{Name, RecordType};
    use proto::xfer::{DnsHandle, DnsRequestOptions};

    use super::*;
    use crate::config::Protocol;

    #[test]
    fn test_name_server() {
        //env_logger::try_init().ok();

        let config = NameServerConfig {
            socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53),
            protocol: Protocol::Udp,
            tls_dns_name: None,
            #[cfg(feature = "dns-over-rustls")]
            tls_config: None,
        };
        let mut io_loop = Runtime::new().unwrap();
        let runtime_handle = io_loop.handle().clone();
        let name_server = future::lazy(|_| {
            NameServer::<_, TokioConnectionProvider>::new(
                config,
                ResolverOpts::default(),
                runtime_handle,
            )
        });

        let name = Name::parse("www.example.com.", None).unwrap();
        let response = io_loop
            .block_on(name_server.then(|mut name_server| {
                name_server.lookup(
                    Query::query(name.clone(), RecordType::A),
                    DnsRequestOptions::default(),
                )
            }))
            .expect("query failed");
        assert_eq!(response.response_code(), ResponseCode::NoError);
    }

    #[test]
    fn test_failed_name_server() {
        let mut options = ResolverOpts::default();
        options.timeout = Duration::from_millis(1); // this is going to fail, make it fail fast...
        let config = NameServerConfig {
            socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 252)), 252),
            protocol: Protocol::Udp,
            tls_dns_name: None,
            #[cfg(feature = "dns-over-rustls")]
            tls_config: None,
        };
        let mut io_loop = Runtime::new().unwrap();
        let runtime_handle = io_loop.handle().clone();
        let name_server = future::lazy(|_| {
            NameServer::<_, TokioConnectionProvider>::new(config, options, runtime_handle)
        });

        let name = Name::parse("www.example.com.", None).unwrap();
        assert!(io_loop
            .block_on(name_server.then(|mut name_server| name_server.lookup(
                Query::query(name.clone(), RecordType::A),
                DnsRequestOptions::default()
            )))
            .is_err());
    }
}
<commit_msg>trigger more name_server errors in more cases<commit_after>// Copyright 2015-2019 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use std::cmp::Ordering;
use std::fmt::{self, Debug, Formatter};
use std::pin::Pin;
use std::sync::Arc;
use std::time::Instant;

use futures::{lock::Mutex, Future};
#[cfg(feature = "tokio-runtime")]
use tokio::runtime::Handle;

use proto::error::{ProtoError, ProtoResult};
#[cfg(feature = "mdns")]
use proto::multicast::MDNS_IPV4;
use proto::op::ResponseCode;
use proto::xfer::{DnsHandle, DnsRequest, DnsResponse};

#[cfg(feature = "mdns")]
use crate::config::Protocol;
use crate::config::{NameServerConfig, ResolverOpts};
use crate::name_server::{ConnectionProvider, NameServerState, NameServerStats};
#[cfg(feature = "tokio-runtime")]
use crate::name_server::{TokioConnection, TokioConnectionProvider};

/// Specifies the details of a remote NameServer used for lookups
#[derive(Clone)]
pub struct NameServer<C: DnsHandle + Send, P: ConnectionProvider<Conn = C> + Send> {
    config: NameServerConfig,
    options: ResolverOpts,
    client: Arc<Mutex<Option<C>>>,
    state: Arc<NameServerState>,
    stats: Arc<NameServerStats>,
    conn_provider: P,
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> Debug for NameServer<C, P> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "config: {:?}, options: {:?}", self.config, self.options)
    }
}

#[cfg(feature = "tokio-runtime")]
impl NameServer<TokioConnection, TokioConnectionProvider> {
    pub fn new(config: NameServerConfig, options: ResolverOpts, runtime: Handle) -> Self {
        Self::new_with_provider(config, options, TokioConnectionProvider::new(runtime))
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> NameServer<C, P> {
    pub fn new_with_provider(
        config: NameServerConfig,
        options: ResolverOpts,
        conn_provider: P,
    ) -> NameServer<C, P> {
        Self {
            config,
            options,
            client: Arc::new(Mutex::new(None)),
            state: Arc::new(NameServerState::init(None)),
            stats: Arc::new(NameServerStats::default()),
            conn_provider,
        }
    }

    #[doc(hidden)]
    pub fn from_conn(
        config: NameServerConfig,
        options: ResolverOpts,
        client: C,
        conn_provider: P,
    ) -> NameServer<C, P> {
        Self {
            config,
            options,
            client: Arc::new(Mutex::new(Some(client))),
            state: Arc::new(NameServerState::init(None)),
            stats: Arc::new(NameServerStats::default()),
            conn_provider,
        }
    }

    #[cfg(test)]
    pub(crate) fn is_connected(&self) -> bool {
        !self.state.is_failed()
            && if let Some(client) = self.client.try_lock() {
                client.is_some()
            } else {
                // assuming that if someone has it locked it will be or is connected
                true
            }
    }

    /// This will return a mutable client to allows for sending messages.
    ///
    /// If the connection is in a failed state, then this will establish a new connection
    async fn connected_mut_client(&mut self) -> ProtoResult<C> {
        let mut client = self.client.lock().await;

        // if this is in a failure state
        if self.state.is_failed() || client.is_none() {
            debug!("reconnecting: {:?}", self.config);

            // TODO: we need the local EDNS options
            self.state.reinit(None);

            let new_client = self
                .conn_provider
                .new_connection(&self.config, &self.options)
                .await?;

            // establish a new connection
            *client = Some(new_client);
        } else {
            debug!("existing connection: {:?}", self.config);
        }

        Ok((*client)
            .clone()
            .expect("bad state, client should be connected"))
    }

    async fn inner_send<R: Into<DnsRequest> + Unpin + Send + 'static>(
        mut self,
        request: R,
    ) -> Result<DnsResponse, ProtoError> {
        let mut client = self.connected_mut_client().await?;
        let response = client.send(request).await;

        match response {
            Ok(response) => {
                // first we'll evaluate if the message succeeded
                //   see https://github.com/bluejekyll/trust-dns/issues/606
                //   TODO: there are probably other return codes from the server we may want to
                //    retry on. We may also want to evaluate NoError responses that lack records as errors as well
                if self.options.distrust_nx_responses {
                    match response.response_code() {
                        ResponseCode::ServFail => {
                            let note = "Nameserver responded with SERVFAIL";
                            debug!("{}", note);
                            return Err(ProtoError::from(note));
                        }
                        ResponseCode::NXDomain => {
                            let note = "Nameserver responded with NXDomain";
                            debug!("{}", note);
                            return Err(ProtoError::from(note));
                        }
                        ResponseCode::NoError if response.answers().is_empty() => {
                            let note = "Nameserver responded with NoError";
                            debug!("{}", note);
                            return Err(ProtoError::from(note));
                        }
                        _ => (),
                    }
                }

                // TODO: consider making message::take_edns...
                let remote_edns = response.edns().cloned();

                // take the remote edns options and store them
                self.state.establish(remote_edns);

                // record the success
                self.stats.next_success();
                Ok(response)
            }
            Err(error) => {
                debug!("name_server connection failure: {}", error);

                // this transitions the state to failure
                self.state.fail(Instant::now());

                // record the failure
                self.stats.next_failure();

                // These are connection failures, not lookup failures, that is handled in the resolver layer
                Err(error)
            }
        }
    }
}

impl<C, P> DnsHandle for NameServer<C, P>
where
    C: DnsHandle,
    P: ConnectionProvider<Conn = C>,
{
    type Response = Pin<Box<dyn Future<Output = Result<DnsResponse, ProtoError>> + Send>>;

    fn is_verifying_dnssec(&self) -> bool {
        self.options.validate
    }

    // TODO: there needs to be some way of customizing the connection based on EDNS options from the server side...
    fn send<R: Into<DnsRequest> + Unpin + Send + 'static>(&mut self, request: R) -> Self::Response {
        let this = self.clone();
        // if state is failed, return future::err(), unless retry delay expired..
        Box::pin(this.inner_send(request))
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> Ord for NameServer<C, P> {
    /// Custom implementation of Ord for NameServer which incorporates the performance of the connection into it's ranking
    fn cmp(&self, other: &Self) -> Ordering {
        // if they are literally equal, just return
        if self == other {
            return Ordering::Equal;
        }

        // otherwise, run our evaluation to determine the next to be returned from the Heap
        //   this will prefer established connections, we should try other connections after
        //   some number to make sure that all are used. This is more important for when
        //   latency is started to be used.
        match self.state.cmp(&other.state) {
            Ordering::Equal => (),
            o => {
                return o;
            }
        }

        self.stats.cmp(&other.stats)
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> PartialOrd for NameServer<C, P> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> PartialEq for NameServer<C, P> {
    /// NameServers are equal if the config (connection information) are equal
    fn eq(&self, other: &Self) -> bool {
        self.config == other.config
    }
}

impl<C: DnsHandle, P: ConnectionProvider<Conn = C>> Eq for NameServer<C, P> {}

// TODO: once IPv6 is better understood, also make this a binary keep.
#[cfg(feature = "mdns")]
pub(crate) fn mdns_nameserver<C, P>(options: ResolverOpts, conn_provider: P) -> NameServer<C, P>
where
    C: DnsHandle,
    P: ConnectionProvider<Conn = C>,
{
    let config = NameServerConfig {
        socket_addr: *MDNS_IPV4,
        protocol: Protocol::Mdns,
        tls_dns_name: None,
        #[cfg(feature = "dns-over-rustls")]
        tls_config: None,
    };
    NameServer::new_with_provider(config, options, conn_provider)
}

#[cfg(test)]
#[cfg(feature = "tokio-runtime")]
mod tests {
    extern crate env_logger;

    use std::net::{IpAddr, Ipv4Addr, SocketAddr};
    use std::time::Duration;

    use futures::{future, FutureExt};
    use tokio::runtime::Runtime;

    use proto::op::{Query, ResponseCode};
    use proto::rr::{Name, RecordType};
    use proto::xfer::{DnsHandle, DnsRequestOptions};

    use super::*;
    use crate::config::Protocol;

    #[test]
    fn test_name_server() {
        //env_logger::try_init().ok();

        let config = NameServerConfig {
            socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53),
            protocol: Protocol::Udp,
            tls_dns_name: None,
            #[cfg(feature = "dns-over-rustls")]
            tls_config: None,
        };
        let mut io_loop = Runtime::new().unwrap();
        let runtime_handle = io_loop.handle().clone();
        let name_server = future::lazy(|_| {
            NameServer::<_, TokioConnectionProvider>::new(
                config,
                ResolverOpts::default(),
                runtime_handle,
            )
        });

        let name = Name::parse("www.example.com.", None).unwrap();
        let response = io_loop
            .block_on(name_server.then(|mut name_server| {
                name_server.lookup(
                    Query::query(name.clone(), RecordType::A),
                    DnsRequestOptions::default(),
                )
            }))
            .expect("query failed");
        assert_eq!(response.response_code(), ResponseCode::NoError);
    }

    #[test]
    fn test_failed_name_server() {
        let mut options = ResolverOpts::default();
        options.timeout = Duration::from_millis(1); // this is going to fail, make it fail fast...
        let config = NameServerConfig {
            socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 252)), 252),
            protocol: Protocol::Udp,
            tls_dns_name: None,
            #[cfg(feature = "dns-over-rustls")]
            tls_config: None,
        };
        let mut io_loop = Runtime::new().unwrap();
        let runtime_handle = io_loop.handle().clone();
        let name_server = future::lazy(|_| {
            NameServer::<_, TokioConnectionProvider>::new(config, options, runtime_handle)
        });

        let name = Name::parse("www.example.com.", None).unwrap();
        assert!(io_loop
            .block_on(name_server.then(|mut name_server| name_server.lookup(
                Query::query(name.clone(), RecordType::A),
                DnsRequestOptions::default()
            )))
            .is_err());
    }
}
<|endoftext|>


<commit_before>use std::cell::UnsafeCell;
use std::rc::Rc;
use std::task::{Context, Poll};

use actix_service::Service;

#[doc(hidden)]
/// Service that allows to turn non-clone service to a service with `Clone` impl
pub(crate) struct CloneableService<T: Service>(Rc<UnsafeCell<T>>);

impl<T: Service> CloneableService<T> {
    pub(crate) fn new(service: T) -> Self {
        Self(Rc::new(UnsafeCell::new(service)))
    }
}

impl<T: Service> Clone for CloneableService<T> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

impl<T: Service> Service for CloneableService<T> {
    type Request = T::Request;
    type Response = T::Response;
    type Error = T::Error;
    type Future = T::Future;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        unsafe { &mut *self.0.as_ref().get() }.poll_ready(cx)
    }

    fn call(&mut self, req: T::Request) -> Self::Future {
        unsafe { &mut *self.0.as_ref().get() }.call(req)
    }
}
<commit_msg>Fixing #1295 convert UnsafeCell to RefCell in CloneableService (#1303)<commit_after>use std::cell::RefCell;
use std::rc::Rc;
use std::task::{Context, Poll};

use actix_service::Service;

#[doc(hidden)]
/// Service that allows to turn non-clone service to a service with `Clone` impl
///
/// # Panics
/// CloneableService might panic with some creative use of thread local storage.
/// See https://github.com/actix/actix-web/issues/1295 for example
pub(crate) struct CloneableService<T: Service>(Rc<RefCell<T>>);

impl<T: Service> CloneableService<T> {
    pub(crate) fn new(service: T) -> Self {
        Self(Rc::new(RefCell::new(service)))
    }
}

impl<T: Service> Clone for CloneableService<T> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

impl<T: Service> Service for CloneableService<T> {
    type Request = T::Request;
    type Response = T::Response;
    type Error = T::Error;
    type Future = T::Future;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.0.borrow_mut().poll_ready(cx)
    }

    fn call(&mut self, req: T::Request) -> Self::Future {
        self.0.borrow_mut().call(req)
    }
}
<|endoftext|>


<commit_before>use time;
use std::io::timer::sleep;
use std::time::duration::Duration;

use {
    Event,
    GenericEvent,
    Input,
    Render,
    RenderArgs,
    Update,
    UpdateArgs,
    Window,
};

use std::cmp;

#[deriving(Show)]
enum EventIteratorState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// Settings for the game loop behavior.
#[deriving(Clone)]
pub struct EventSettings {
    /// The number of updates per second (UPS).
    pub updates_per_second: u64,
    /// The maximum number of frames per second (FPS target).
    pub max_frames_per_second: u64,
}

/// A game loop iterator.
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// let event_settings = EventSettings {
///     updates_per_second: 120,
///     max_frames_per_second: 60,
/// };
/// let ref mut gl = Gl::new();
/// for e in EventIterator::new(&mut window, &event_settings) {
///     match e {
///         Render(args) => {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         },
///     }
/// }
/// ```
pub struct EventIterator<'a, W: 'a> {
    /// The game window used by iterator.
    pub window: &'a mut W,
    state: EventIteratorState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

impl<'a, W: Window<I>, I: GenericEvent> EventIterator<'a, W> {
    /// Creates a new game iterator.
    pub fn new(
        window: &'a mut W,
        settings: &EventSettings
    ) -> EventIterator<'a, W> {
        let updates_per_second: u64 = settings.updates_per_second;
        let max_frames_per_second: u64 = settings.max_frames_per_second;

        let start = time::precise_time_ns();
        EventIterator {
            window: window,
            state: RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<'a, W: Window<I>, I: GenericEvent>
Iterator<Event<I>>
for EventIterator<'a, W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<Event<I>> {
        loop {
            self.state = match self.state {
                RenderState => {
                    if self.window.should_close() { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let (w, h) = self.window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = SwapBuffersState;
                        return Some(Render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    UpdateLoopState
                }
                SwapBuffersState => {
                    self.window.swap_buffers();
                    UpdateLoopState
                }
                UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        UpdateLoopState
                    } else if next_event == next_frame {
                        RenderState
                    } else {
                        HandleEventsState
                    }
                }
                HandleEventsState => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => UpdateState,
                        Some(x) => { return Some(Input(x)); },
                    }
                }
                UpdateState => {
                    self.state = UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(Update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<commit_msg>Passing `&RefCell<W>` instead of `&mut T`<commit_after>use time;
use std::io::timer::sleep;
use std::time::duration::Duration;
use std::cell::RefCell;

use {
    Event,
    GenericEvent,
    Input,
    Render,
    RenderArgs,
    Update,
    UpdateArgs,
    Window,
};

use std::cmp;

#[deriving(Show)]
enum EventIteratorState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// Settings for the game loop behavior.
#[deriving(Clone)]
pub struct EventSettings {
    /// The number of updates per second (UPS).
    pub updates_per_second: u64,
    /// The maximum number of frames per second (FPS target).
    pub max_frames_per_second: u64,
}

/// A game loop iterator.
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// let event_settings = EventSettings {
///     updates_per_second: 120,
///     max_frames_per_second: 60,
/// };
/// let ref mut gl = Gl::new();
/// for e in EventIterator::new(&mut window, &event_settings) {
///     match e {
///         Render(args) => {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         },
///     }
/// }
/// ```
pub struct EventIterator<'a, W: 'a> {
    /// The game window used by iterator.
    pub window: &'a RefCell<W>,
    state: EventIteratorState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

impl<'a, W: Window<I>, I: GenericEvent> EventIterator<'a, W> {
    /// Creates a new game iterator.
    /// Uses a `RefCell` reference to the window,
    /// because it is likely to be access elsewhere while polling events.
    pub fn new(
        window: &'a RefCell<W>,
        settings: &EventSettings
    ) -> EventIterator<'a, W> {
        let updates_per_second: u64 = settings.updates_per_second;
        let max_frames_per_second: u64 = settings.max_frames_per_second;

        let start = time::precise_time_ns();
        EventIterator {
            window: window,
            state: RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<'a, W: Window<I>, I: GenericEvent>
Iterator<Event<I>>
for EventIterator<'a, W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<Event<I>> {
        let mut window = self.window.borrow_mut();
        loop {
            self.state = match self.state {
                RenderState => {
                    if window.should_close() { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let (w, h) = window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = SwapBuffersState;
                        return Some(Render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    UpdateLoopState
                }
                SwapBuffersState => {
                    window.swap_buffers();
                    UpdateLoopState
                }
                UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        UpdateLoopState
                    } else if next_event == next_frame {
                        RenderState
                    } else {
                        HandleEventsState
                    }
                }
                HandleEventsState => {
                    // Handle all events before updating.
                    match window.poll_event() {
                        None => UpdateState,
                        Some(x) => { return Some(Input(x)); },
                    }
                }
                UpdateState => {
                    self.state = UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(Update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<|endoftext|>


<commit_before>use crate::clippy_project_root;
use shell_escape::escape;
use std::ffi::OsStr;
use std::path::Path;
use std::process::{self, Command};
use std::{fs, io};
use walkdir::WalkDir;

#[derive(Debug)]
pub enum CliError {
    CommandFailed(String),
    IoError(io::Error),
    RustfmtNotInstalled,
    WalkDirError(walkdir::Error),
    RaSetupActive,
}

impl From<io::Error> for CliError {
    fn from(error: io::Error) -> Self {
        Self::IoError(error)
    }
}

impl From<walkdir::Error> for CliError {
    fn from(error: walkdir::Error) -> Self {
        Self::WalkDirError(error)
    }
}

struct FmtContext {
    check: bool,
    verbose: bool,
}

// the "main" function of cargo dev fmt
pub fn run(check: bool, verbose: bool) {
    fn try_run(context: &FmtContext) -> Result<bool, CliError> {
        let mut success = true;

        let project_root = clippy_project_root();

        // if we added a local rustc repo as path dependency to clippy for rust analyzer, we do NOT want to
        // format because rustfmt would also format the entire rustc repo as it is a local
        // dependency
        if fs::read_to_string(project_root.join("Cargo.toml"))
            .expect("Failed to read clippy Cargo.toml")
            .contains(&"[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
        {
            return Err(CliError::RaSetupActive);
        }

        rustfmt_test(context)?;

        success &= cargo_fmt(context, project_root.as_path())?;
        success &= cargo_fmt(context, &project_root.join("clippy_dev"))?;
        success &= cargo_fmt(context, &project_root.join("rustc_tools_util"))?;

        for entry in WalkDir::new(project_root.join("tests")) {
            let entry = entry?;
            let path = entry.path();

            if path.extension() != Some("rs".as_ref())
                || entry.file_name() == "ice-3891.rs"
                // Avoid rustfmt bug rust-lang/rustfmt#1873
                || cfg!(windows) && entry.file_name() == "implicit_hasher.rs"
            {
                continue;
            }

            success &= rustfmt(context, &path)?;
        }

        Ok(success)
    }

    fn output_err(err: CliError) {
        match err {
            CliError::CommandFailed(command) => {
                eprintln!("error: A command failed! `{}`", command);
            },
            CliError::IoError(err) => {
                eprintln!("error: {}", err);
            },
            CliError::RustfmtNotInstalled => {
                eprintln!("error: rustfmt nightly is not installed.");
            },
            CliError::WalkDirError(err) => {
                eprintln!("error: {}", err);
            },
            CliError::RaSetupActive => {
                eprintln!(
                    "error: a local rustc repo is enabled as path dependency via `cargo dev ra_setup`.
Not formatting because that would format the local repo as well!
Please revert the changes to Cargo.tomls first."
                );
            },
        }
    }

    let context = FmtContext { check, verbose };
    let result = try_run(&context);
    let code = match result {
        Ok(true) => 0,
        Ok(false) => {
            eprintln!();
            eprintln!("Formatting check failed.");
            eprintln!("Run `cargo dev fmt` to update formatting.");
            1
        },
        Err(err) => {
            output_err(err);
            1
        },
    };
    process::exit(code);
}

fn format_command(program: impl AsRef<OsStr>, dir: impl AsRef<Path>, args: &[impl AsRef<OsStr>]) -> String {
    let arg_display: Vec<_> = args.iter().map(|a| escape(a.as_ref().to_string_lossy())).collect();

    format!(
        "cd {} && {} {}",
        escape(dir.as_ref().to_string_lossy()),
        escape(program.as_ref().to_string_lossy()),
        arg_display.join(" ")
    )
}

fn exec(
    context: &FmtContext,
    program: impl AsRef<OsStr>,
    dir: impl AsRef<Path>,
    args: &[impl AsRef<OsStr>],
) -> Result<bool, CliError> {
    if context.verbose {
        println!("{}", format_command(&program, &dir, args));
    }

    let mut child = Command::new(&program).current_dir(&dir).args(args.iter()).spawn()?;
    let code = child.wait()?;
    let success = code.success();

    if !context.check && !success {
        return Err(CliError::CommandFailed(format_command(&program, &dir, args)));
    }

    Ok(success)
}

fn cargo_fmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
    let mut args = vec!["+nightly", "fmt", "--all"];
    if context.check {
        args.push("--");
        args.push("--check");
    }
    let success = exec(context, "cargo", path, &args)?;

    Ok(success)
}

fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
    let program = "rustfmt";
    let dir = std::env::current_dir()?;
    let args = &["+nightly", "--version"];

    if context.verbose {
        println!("{}", format_command(&program, &dir, args));
    }

    let output = Command::new(&program).current_dir(&dir).args(args.iter()).output()?;

    if output.status.success() {
        Ok(())
    } else if std::str::from_utf8(&output.stderr)
        .unwrap_or("")
        .starts_with("error: 'rustfmt' is not installed")
    {
        Err(CliError::RustfmtNotInstalled)
    } else {
        Err(CliError::CommandFailed(format_command(&program, &dir, args)))
    }
}

fn rustfmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
    let mut args = vec!["+nightly".as_ref(), path.as_os_str()];
    if context.check {
        args.push("--check".as_ref());
    }
    let success = exec(context, "rustfmt", std::env::current_dir()?, &args)?;
    if !success {
        eprintln!("rustfmt failed on {}", path.display());
    }
    Ok(success)
}
<commit_msg>Auto merge of #6656 - phansch:command-failed-print-stderr, r=flip1995<commit_after>use crate::clippy_project_root;
use shell_escape::escape;
use std::ffi::OsStr;
use std::path::Path;
use std::process::{self, Command};
use std::{fs, io};
use walkdir::WalkDir;

#[derive(Debug)]
pub enum CliError {
    CommandFailed(String, String),
    IoError(io::Error),
    RustfmtNotInstalled,
    WalkDirError(walkdir::Error),
    RaSetupActive,
}

impl From<io::Error> for CliError {
    fn from(error: io::Error) -> Self {
        Self::IoError(error)
    }
}

impl From<walkdir::Error> for CliError {
    fn from(error: walkdir::Error) -> Self {
        Self::WalkDirError(error)
    }
}

struct FmtContext {
    check: bool,
    verbose: bool,
}

// the "main" function of cargo dev fmt
pub fn run(check: bool, verbose: bool) {
    fn try_run(context: &FmtContext) -> Result<bool, CliError> {
        let mut success = true;

        let project_root = clippy_project_root();

        // if we added a local rustc repo as path dependency to clippy for rust analyzer, we do NOT want to
        // format because rustfmt would also format the entire rustc repo as it is a local
        // dependency
        if fs::read_to_string(project_root.join("Cargo.toml"))
            .expect("Failed to read clippy Cargo.toml")
            .contains(&"[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
        {
            return Err(CliError::RaSetupActive);
        }

        rustfmt_test(context)?;

        success &= cargo_fmt(context, project_root.as_path())?;
        success &= cargo_fmt(context, &project_root.join("clippy_dev"))?;
        success &= cargo_fmt(context, &project_root.join("rustc_tools_util"))?;

        for entry in WalkDir::new(project_root.join("tests")) {
            let entry = entry?;
            let path = entry.path();

            if path.extension() != Some("rs".as_ref())
                || entry.file_name() == "ice-3891.rs"
                // Avoid rustfmt bug rust-lang/rustfmt#1873
                || cfg!(windows) && entry.file_name() == "implicit_hasher.rs"
            {
                continue;
            }

            success &= rustfmt(context, &path)?;
        }

        Ok(success)
    }

    fn output_err(err: CliError) {
        match err {
            CliError::CommandFailed(command, stderr) => {
                eprintln!("error: A command failed! `{}`\nstderr: {}", command, stderr);
            },
            CliError::IoError(err) => {
                eprintln!("error: {}", err);
            },
            CliError::RustfmtNotInstalled => {
                eprintln!("error: rustfmt nightly is not installed.");
            },
            CliError::WalkDirError(err) => {
                eprintln!("error: {}", err);
            },
            CliError::RaSetupActive => {
                eprintln!(
                    "error: a local rustc repo is enabled as path dependency via `cargo dev ra_setup`.
Not formatting because that would format the local repo as well!
Please revert the changes to Cargo.tomls first."
                );
            },
        }
    }

    let context = FmtContext { check, verbose };
    let result = try_run(&context);
    let code = match result {
        Ok(true) => 0,
        Ok(false) => {
            eprintln!();
            eprintln!("Formatting check failed.");
            eprintln!("Run `cargo dev fmt` to update formatting.");
            1
        },
        Err(err) => {
            output_err(err);
            1
        },
    };
    process::exit(code);
}

fn format_command(program: impl AsRef<OsStr>, dir: impl AsRef<Path>, args: &[impl AsRef<OsStr>]) -> String {
    let arg_display: Vec<_> = args.iter().map(|a| escape(a.as_ref().to_string_lossy())).collect();

    format!(
        "cd {} && {} {}",
        escape(dir.as_ref().to_string_lossy()),
        escape(program.as_ref().to_string_lossy()),
        arg_display.join(" ")
    )
}

fn exec(
    context: &FmtContext,
    program: impl AsRef<OsStr>,
    dir: impl AsRef<Path>,
    args: &[impl AsRef<OsStr>],
) -> Result<bool, CliError> {
    if context.verbose {
        println!("{}", format_command(&program, &dir, args));
    }

    let child = Command::new(&program).current_dir(&dir).args(args.iter()).spawn()?;
    let output = child.wait_with_output()?;
    let success = output.status.success();

    if !context.check && !success {
        let stderr = std::str::from_utf8(&output.stderr).unwrap_or("");
        return Err(CliError::CommandFailed(
            format_command(&program, &dir, args),
            String::from(stderr),
        ));
    }

    Ok(success)
}

fn cargo_fmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
    let mut args = vec!["+nightly", "fmt", "--all"];
    if context.check {
        args.push("--");
        args.push("--check");
    }
    let success = exec(context, "cargo", path, &args)?;

    Ok(success)
}

fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
    let program = "rustfmt";
    let dir = std::env::current_dir()?;
    let args = &["+nightly", "--version"];

    if context.verbose {
        println!("{}", format_command(&program, &dir, args));
    }

    let output = Command::new(&program).current_dir(&dir).args(args.iter()).output()?;

    if output.status.success() {
        Ok(())
    } else if std::str::from_utf8(&output.stderr)
        .unwrap_or("")
        .starts_with("error: 'rustfmt' is not installed")
    {
        Err(CliError::RustfmtNotInstalled)
    } else {
        Err(CliError::CommandFailed(
            format_command(&program, &dir, args),
            std::str::from_utf8(&output.stderr).unwrap_or("").to_string(),
        ))
    }
}

fn rustfmt(context: &FmtContext, path: &Path) -> Result<bool, CliError> {
    let mut args = vec!["+nightly".as_ref(), path.as_os_str()];
    if context.check {
        args.push("--check".as_ref());
    }
    let success = exec(context, "rustfmt", std::env::current_dir()?, &args)?;
    if !success {
        eprintln!("rustfmt failed on {}", path.display());
    }
    Ok(success)
}
<|endoftext|>


<commit_before>pub static vertex_src: &'static str =
   "#version 150                                                    \n\
    in vec3 position;                                               \n\
    in vec3 normal;                                                 \n\
    in vec3 color;                                                  \n\
    out vec3 Color;                                                 \n\
    out vec3 ws_normal;                                             \n\
    out vec3 ws_position;                                           \n\
    uniform mat4 projection;                                        \n\
    uniform mat4 transform;                                         \n\
    uniform mat3 ntransform;                                        \n\
    void main() {                                                   \n\
        Color       = color;                                        \n\
        vec4 pos4   = transform * vec4(position, 1.0);              \n\
        ws_position = pos4.xyz;                                     \n\
        gl_Position = projection * transform * vec4(position, 1.0); \n\
        ws_normal   = normalize(ntransform * normal);               \n\
    }";

// phong lighting (heavily) inspired
// by http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/lighting.php
pub static fragment_src: &'static str =
   "#version 150                     \n\
    uniform vec3 color;              \n\
    uniform vec3 light_position;     \n\
    in  vec3 ws_normal;              \n\
    in  vec3 ws_position;            \n\
    out vec4 outColor;               \n\
    void main() {                    \n\
      vec3 L = normalize(light_position - ws_position);   \n\
      vec3 E = normalize(-ws_position);                   \n\
      vec3 R = normalize(-reflect(L, ws_normal));         \n\
                                                          \n\
      //calculate Ambient Term:                           \n\
      vec4 Iamb = vec4(0.1, 0.1, 0.1, 1.0);               \n\
                                                          \n\
      //calculate Diffuse Term:                           \n\
      vec4 Idiff = vec4(0.5, 0.5, 0.5, 1.0) * max(dot(ws_normal,L), 0.0); \n\
      Idiff = clamp(Idiff, 0.0, 1.0);                                     \n\
                                                                          \n\
      // calculate Specular Term:                                         \n\
      vec4 Ispec = vec4(0.3, 0.3, 0.3, 1.0)                               \n\
                   * pow(max(dot(R, E), 0.0), 0.3 * 10.0);                \n\
      Ispec = clamp(Ispec, 0.0, 1.0);                                     \n\
                                                                          \n\
      outColor = vec4(color, 1.0) + Iamb + Idiff + Ispec;                 \n\
    }";
<commit_msg>Made the specular light less strong.<commit_after>pub static vertex_src: &'static str =
   "#version 150                                                    \n\
    in vec3 position;                                               \n\
    in vec3 normal;                                                 \n\
    in vec3 color;                                                  \n\
    out vec3 Color;                                                 \n\
    out vec3 ws_normal;                                             \n\
    out vec3 ws_position;                                           \n\
    uniform mat4 projection;                                        \n\
    uniform mat4 transform;                                         \n\
    uniform mat3 ntransform;                                        \n\
    void main() {                                                   \n\
        Color       = color;                                        \n\
        vec4 pos4   = transform * vec4(position, 1.0);              \n\
        ws_position = pos4.xyz;                                     \n\
        gl_Position = projection * transform * vec4(position, 1.0); \n\
        ws_normal   = normalize(ntransform * normal);               \n\
    }";

// phong lighting (heavily) inspired
// by http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/lighting.php
pub static fragment_src: &'static str =
   "#version 150                     \n\
    uniform vec3 color;              \n\
    uniform vec3 light_position;     \n\
    in  vec3 ws_normal;              \n\
    in  vec3 ws_position;            \n\
    out vec4 outColor;               \n\
    void main() {                    \n\
      vec3 L = normalize(light_position - ws_position);   \n\
      vec3 E = normalize(-ws_position);                   \n\
      vec3 R = normalize(-reflect(L, ws_normal));         \n\
                                                          \n\
      //calculate Ambient Term:                           \n\
      vec4 Iamb = vec4(0.1, 0.1, 0.1, 1.0);               \n\
                                                          \n\
      //calculate Diffuse Term:                           \n\
      vec4 Idiff = vec4(0.5, 0.5, 0.5, 1.0) * max(dot(ws_normal,L), 0.0); \n\
      Idiff = clamp(Idiff, 0.0, 1.0);                                     \n\
                                                                          \n\
      // calculate Specular Term:                                         \n\
      vec4 Ispec = vec4(0.1, 0.1, 0.1, 1.0)                               \n\
                   * pow(max(dot(R, E), 0.0), 0.3 * 10.0);                \n\
      Ispec = clamp(Ispec, 0.0, 1.0);                                     \n\
                                                                          \n\
      outColor = vec4(color, 1.0) + Iamb + Idiff + Ispec;                 \n\
    }";
<|endoftext|>