<commit_before>use std::cell::RefCell;

use itertools::Itertools;
use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}};
use ra_db::SourceDatabase;
use ra_syntax::{
    Location, SourceFile, SyntaxKind, TextRange, SyntaxNode,
    ast::{self, AstNode},
};
use ra_text_edit::{TextEdit, TextEditBuilder};

use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit, db::RootDatabase};

#[derive(Debug, Copy, Clone)]
pub enum Severity {
    Error,
    WeakWarning,
}

pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> {
    let source_file = db.parse(file_id);
    let mut res = Vec::new();

    syntax_errors(&mut res, &source_file);

    for node in source_file.syntax().descendants() {
        check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
        check_struct_shorthand_initialization(&mut res, file_id, node);
    }
    let res = RefCell::new(res);
    let mut sink = DiagnosticSink::new(|d| {
        res.borrow_mut().push(Diagnostic {
            message: d.message(),
            range: d.highlight_range(),
            severity: Severity::Error,
            fix: None,
        })
    })
    .on::<hir::diagnostics::UnresolvedModule, _>(|d| {
        let source_root = db.file_source_root(d.file().original_file(db));
        let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() };
        let fix = SourceChange::file_system_edit("create module", create_file);
        res.borrow_mut().push(Diagnostic {
            range: d.highlight_range(),
            message: d.message(),
            severity: Severity::Error,
            fix: Some(fix),
        })
    });
    if let Some(m) = source_binder::module_from_file_id(db, file_id) {
        m.diagnostics(db, &mut sink);
    };
    drop(sink);
    res.into_inner()
}

fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) {
    fn location_to_range(location: Location) -> TextRange {
        match location {
            Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
            Location::Range(range) => range,
        }
    }

    acc.extend(source_file.errors().into_iter().map(|err| Diagnostic {
        range: location_to_range(err.location()),
        message: format!("Syntax Error: {}", err),
        severity: Severity::Error,
        fix: None,
    }));
}

fn check_unnecessary_braces_in_use_statement(
    acc: &mut Vec<Diagnostic>,
    file_id: FileId,
    node: &SyntaxNode,
) -> Option<()> {
    let use_tree_list = ast::UseTreeList::cast(node)?;
    if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() {
        let range = use_tree_list.syntax().range();
        let edit =
            text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(single_use_tree)
                .unwrap_or_else(|| {
                    let to_replace = single_use_tree.syntax().text().to_string();
                    let mut edit_builder = TextEditBuilder::default();
                    edit_builder.delete(range);
                    edit_builder.insert(range.start(), to_replace);
                    edit_builder.finish()
                });

        acc.push(Diagnostic {
            range,
            message: format!("Unnecessary braces in use statement"),
            severity: Severity::WeakWarning,
            fix: Some(SourceChange::source_file_edit(
                "Remove unnecessary braces",
                SourceFileEdit { file_id, edit },
            )),
        });
    }

    Some(())
}

fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
    single_use_tree: &ast::UseTree,
) -> Option<TextEdit> {
    let use_tree_list_node = single_use_tree.syntax().parent()?;
    if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind()
        == SyntaxKind::SELF_KW
    {
        let start = use_tree_list_node.prev_sibling_or_token()?.range().start();
        let end = use_tree_list_node.range().end();
        let range = TextRange::from_to(start, end);
        let mut edit_builder = TextEditBuilder::default();
        edit_builder.delete(range);
        return Some(edit_builder.finish());
    }
    None
}

fn check_struct_shorthand_initialization(
    acc: &mut Vec<Diagnostic>,
    file_id: FileId,
    node: &SyntaxNode,
) -> Option<()> {
    let struct_lit = ast::StructLit::cast(node)?;
    let named_field_list = struct_lit.named_field_list()?;
    for named_field in named_field_list.fields() {
        if let (Some(name_ref), Some(expr)) = (named_field.name_ref(), named_field.expr()) {
            let field_name = name_ref.syntax().text().to_string();
            let field_expr = expr.syntax().text().to_string();
            if field_name == field_expr {
                let mut edit_builder = TextEditBuilder::default();
                edit_builder.delete(named_field.syntax().range());
                edit_builder.insert(named_field.syntax().range().start(), field_name);
                let edit = edit_builder.finish();

                acc.push(Diagnostic {
                    range: named_field.syntax().range(),
                    message: format!("Shorthand struct initialization"),
                    severity: Severity::WeakWarning,
                    fix: Some(SourceChange::source_file_edit(
                        "use struct shorthand initialization",
                        SourceFileEdit { file_id, edit },
                    )),
                });
            }
        }
    }
    Some(())
}

#[cfg(test)]
mod tests {
    use test_utils::assert_eq_text;
    use insta::assert_debug_snapshot_matches;

    use crate::mock_analysis::single_file;

    use super::*;

    type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>;

    fn check_not_applicable(code: &str, func: DiagnosticChecker) {
        let file = SourceFile::parse(code);
        let mut diagnostics = Vec::new();
        for node in file.syntax().descendants() {
            func(&mut diagnostics, FileId(0), node);
        }
        assert!(diagnostics.is_empty());
    }

    fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
        let file = SourceFile::parse(before);
        let mut diagnostics = Vec::new();
        for node in file.syntax().descendants() {
            func(&mut diagnostics, FileId(0), node);
        }
        let diagnostic =
            diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before));
        let mut fix = diagnostic.fix.unwrap();
        let edit = fix.source_file_edits.pop().unwrap().edit;
        let actual = edit.apply(&before);
        assert_eq_text!(after, &actual);
    }

    #[test]
    fn test_unresolved_module_diagnostic() {
        let (analysis, file_id) = single_file("mod foo;");
        let diagnostics = analysis.diagnostics(file_id).unwrap();
        assert_debug_snapshot_matches!(diagnostics, @r####"[
    Diagnostic {
        message: "unresolved module",
        range: [0; 8),
        fix: Some(
            SourceChange {
                label: "create module",
                source_file_edits: [],
                file_system_edits: [
                    CreateFile {
                        source_root: SourceRootId(
                            0
                        ),
                        path: "foo.rs"
                    }
                ],
                cursor_position: None
            }
        ),
        severity: Error
    }
]"####);
    }

    #[test]
    fn test_check_unnecessary_braces_in_use_statement() {
        check_not_applicable(
            "
            use a;
            use a::{c, d::e};
        ",
            check_unnecessary_braces_in_use_statement,
        );
        check_apply("use {b};", "use b;", check_unnecessary_braces_in_use_statement);
        check_apply("use a::{c};", "use a::c;", check_unnecessary_braces_in_use_statement);
        check_apply("use a::{self};", "use a;", check_unnecessary_braces_in_use_statement);
        check_apply(
            "use a::{c, d::{e}};",
            "use a::{c, d::e};",
            check_unnecessary_braces_in_use_statement,
        );
    }

    #[test]
    fn test_check_struct_shorthand_initialization() {
        check_not_applicable(
            r#"
            struct A {
                a: &'static str
            }

            fn main() {
                A {
                    a: "hello"
                }
            }
        "#,
            check_struct_shorthand_initialization,
        );

        check_apply(
            r#"
struct A {
    a: &'static str
}

fn main() {
    let a = "haha";
    A {
        a: a
    }
}
        "#,
            r#"
struct A {
    a: &'static str
}

fn main() {
    let a = "haha";
    A {
        a
    }
}
        "#,
            check_struct_shorthand_initialization,
        );

        check_apply(
            r#"
struct A {
    a: &'static str,
    b: &'static str
}

fn main() {
    let a = "haha";
    let b = "bb";
    A {
        a: a,
        b
    }
}
        "#,
            r#"
struct A {
    a: &'static str,
    b: &'static str
}

fn main() {
    let a = "haha";
    let b = "bb";
    A {
        a,
        b
    }
}
        "#,
            check_struct_shorthand_initialization,
        );
    }
}
<commit_msg>Profile diagnostics.<commit_after>use std::cell::RefCell;

use itertools::Itertools;
use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}};
use ra_db::SourceDatabase;
use ra_syntax::{
    Location, SourceFile, SyntaxKind, TextRange, SyntaxNode,
    ast::{self, AstNode},
};
use ra_text_edit::{TextEdit, TextEditBuilder};
use ra_prof::profile;

use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit, db::RootDatabase};

#[derive(Debug, Copy, Clone)]
pub enum Severity {
    Error,
    WeakWarning,
}

pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> {
    let _p = profile("diagnostics");
    let source_file = db.parse(file_id);
    let mut res = Vec::new();

    syntax_errors(&mut res, &source_file);

    for node in source_file.syntax().descendants() {
        check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
        check_struct_shorthand_initialization(&mut res, file_id, node);
    }
    let res = RefCell::new(res);
    let mut sink = DiagnosticSink::new(|d| {
        res.borrow_mut().push(Diagnostic {
            message: d.message(),
            range: d.highlight_range(),
            severity: Severity::Error,
            fix: None,
        })
    })
    .on::<hir::diagnostics::UnresolvedModule, _>(|d| {
        let source_root = db.file_source_root(d.file().original_file(db));
        let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() };
        let fix = SourceChange::file_system_edit("create module", create_file);
        res.borrow_mut().push(Diagnostic {
            range: d.highlight_range(),
            message: d.message(),
            severity: Severity::Error,
            fix: Some(fix),
        })
    });
    if let Some(m) = source_binder::module_from_file_id(db, file_id) {
        m.diagnostics(db, &mut sink);
    };
    drop(sink);
    res.into_inner()
}

fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) {
    fn location_to_range(location: Location) -> TextRange {
        match location {
            Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
            Location::Range(range) => range,
        }
    }

    acc.extend(source_file.errors().into_iter().map(|err| Diagnostic {
        range: location_to_range(err.location()),
        message: format!("Syntax Error: {}", err),
        severity: Severity::Error,
        fix: None,
    }));
}

fn check_unnecessary_braces_in_use_statement(
    acc: &mut Vec<Diagnostic>,
    file_id: FileId,
    node: &SyntaxNode,
) -> Option<()> {
    let use_tree_list = ast::UseTreeList::cast(node)?;
    if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() {
        let range = use_tree_list.syntax().range();
        let edit =
            text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(single_use_tree)
                .unwrap_or_else(|| {
                    let to_replace = single_use_tree.syntax().text().to_string();
                    let mut edit_builder = TextEditBuilder::default();
                    edit_builder.delete(range);
                    edit_builder.insert(range.start(), to_replace);
                    edit_builder.finish()
                });

        acc.push(Diagnostic {
            range,
            message: format!("Unnecessary braces in use statement"),
            severity: Severity::WeakWarning,
            fix: Some(SourceChange::source_file_edit(
                "Remove unnecessary braces",
                SourceFileEdit { file_id, edit },
            )),
        });
    }

    Some(())
}

fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
    single_use_tree: &ast::UseTree,
) -> Option<TextEdit> {
    let use_tree_list_node = single_use_tree.syntax().parent()?;
    if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind()
        == SyntaxKind::SELF_KW
    {
        let start = use_tree_list_node.prev_sibling_or_token()?.range().start();
        let end = use_tree_list_node.range().end();
        let range = TextRange::from_to(start, end);
        let mut edit_builder = TextEditBuilder::default();
        edit_builder.delete(range);
        return Some(edit_builder.finish());
    }
    None
}

fn check_struct_shorthand_initialization(
    acc: &mut Vec<Diagnostic>,
    file_id: FileId,
    node: &SyntaxNode,
) -> Option<()> {
    let struct_lit = ast::StructLit::cast(node)?;
    let named_field_list = struct_lit.named_field_list()?;
    for named_field in named_field_list.fields() {
        if let (Some(name_ref), Some(expr)) = (named_field.name_ref(), named_field.expr()) {
            let field_name = name_ref.syntax().text().to_string();
            let field_expr = expr.syntax().text().to_string();
            if field_name == field_expr {
                let mut edit_builder = TextEditBuilder::default();
                edit_builder.delete(named_field.syntax().range());
                edit_builder.insert(named_field.syntax().range().start(), field_name);
                let edit = edit_builder.finish();

                acc.push(Diagnostic {
                    range: named_field.syntax().range(),
                    message: format!("Shorthand struct initialization"),
                    severity: Severity::WeakWarning,
                    fix: Some(SourceChange::source_file_edit(
                        "use struct shorthand initialization",
                        SourceFileEdit { file_id, edit },
                    )),
                });
            }
        }
    }
    Some(())
}

#[cfg(test)]
mod tests {
    use test_utils::assert_eq_text;
    use insta::assert_debug_snapshot_matches;

    use crate::mock_analysis::single_file;

    use super::*;

    type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>;

    fn check_not_applicable(code: &str, func: DiagnosticChecker) {
        let file = SourceFile::parse(code);
        let mut diagnostics = Vec::new();
        for node in file.syntax().descendants() {
            func(&mut diagnostics, FileId(0), node);
        }
        assert!(diagnostics.is_empty());
    }

    fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
        let file = SourceFile::parse(before);
        let mut diagnostics = Vec::new();
        for node in file.syntax().descendants() {
            func(&mut diagnostics, FileId(0), node);
        }
        let diagnostic =
            diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before));
        let mut fix = diagnostic.fix.unwrap();
        let edit = fix.source_file_edits.pop().unwrap().edit;
        let actual = edit.apply(&before);
        assert_eq_text!(after, &actual);
    }

    #[test]
    fn test_unresolved_module_diagnostic() {
        let (analysis, file_id) = single_file("mod foo;");
        let diagnostics = analysis.diagnostics(file_id).unwrap();
        assert_debug_snapshot_matches!(diagnostics, @r####"[
    Diagnostic {
        message: "unresolved module",
        range: [0; 8),
        fix: Some(
            SourceChange {
                label: "create module",
                source_file_edits: [],
                file_system_edits: [
                    CreateFile {
                        source_root: SourceRootId(
                            0
                        ),
                        path: "foo.rs"
                    }
                ],
                cursor_position: None
            }
        ),
        severity: Error
    }
]"####);
    }

    #[test]
    fn test_check_unnecessary_braces_in_use_statement() {
        check_not_applicable(
            "
            use a;
            use a::{c, d::e};
        ",
            check_unnecessary_braces_in_use_statement,
        );
        check_apply("use {b};", "use b;", check_unnecessary_braces_in_use_statement);
        check_apply("use a::{c};", "use a::c;", check_unnecessary_braces_in_use_statement);
        check_apply("use a::{self};", "use a;", check_unnecessary_braces_in_use_statement);
        check_apply(
            "use a::{c, d::{e}};",
            "use a::{c, d::e};",
            check_unnecessary_braces_in_use_statement,
        );
    }

    #[test]
    fn test_check_struct_shorthand_initialization() {
        check_not_applicable(
            r#"
            struct A {
                a: &'static str
            }

            fn main() {
                A {
                    a: "hello"
                }
            }
        "#,
            check_struct_shorthand_initialization,
        );

        check_apply(
            r#"
struct A {
    a: &'static str
}

fn main() {
    let a = "haha";
    A {
        a: a
    }
}
        "#,
            r#"
struct A {
    a: &'static str
}

fn main() {
    let a = "haha";
    A {
        a
    }
}
        "#,
            check_struct_shorthand_initialization,
        );

        check_apply(
            r#"
struct A {
    a: &'static str,
    b: &'static str
}

fn main() {
    let a = "haha";
    let b = "bb";
    A {
        a: a,
        b
    }
}
        "#,
            r#"
struct A {
    a: &'static str,
    b: &'static str
}

fn main() {
    let a = "haha";
    let b = "bb";
    A {
        a,
        b
    }
}
        "#,
            check_struct_shorthand_initialization,
        );
    }
}
<|endoftext|>


<commit_before>// OpenAOE: An open source reimplementation of Age of Empires (1997)
// Copyright (c) 2016 Kevin Fuller
//
// 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.

use drs::DrsFileType;
use drs_manager::{DrsKey, DrsManagerRef};
use error::*;
use identifier::{PlayerColorId, SlpFileId};
use media::{Renderer, Texture, TextureBuilder};

use nalgebra::Vector2;
use palette::{self, PaletteColor};
use slp::SlpFile;

use std::cell::RefCell;
use std::collections::HashMap;
use std::io;
use std::rc::Rc;
use types::Rect;

const SHAPE_PADDING: i32 = 4;
const PALETTE_FILE_ID: u32 = 50500;

#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)]
pub struct ShapeKey {
    pub drs_key: DrsKey,
    pub slp_id: SlpFileId,
    pub player_color: PlayerColorId,
}

impl ShapeKey {
    pub fn new(drs_key: DrsKey, slp_id: SlpFileId, player_color: PlayerColorId) -> ShapeKey {
        ShapeKey {
            drs_key: drs_key,
            slp_id: slp_id,
            player_color: player_color,
        }
    }
}

pub struct Shape {
    texture: Texture,
    frames: Vec<Rect>,
    centers: Vec<Vector2<i32>>,
}

impl Shape {
    fn load_from(slp: &SlpFile, palette: &[u32], renderer: &mut Renderer) -> Result<Shape> {
        let mut total_rect = Rect::new();
        let mut dst_rects = Vec::new();
        let mut centers = Vec::new();
        let mut next_x = 0i32;
        for shape in &slp.shapes {
            let dst_rect = Rect::of(next_x,
                                    0,
                                    shape.header.width as i32,
                                    shape.header.height as i32);
            dst_rects.push(dst_rect);
            centers.push(Vector2::new(shape.header.center_x, shape.header.center_y));

            total_rect.extend(&dst_rect);
            next_x += shape.header.width as i32 + SHAPE_PADDING;
        }

        let mut texture_builder =
            try!(TextureBuilder::new(total_rect.w as u32, total_rect.h as u32, &palette));
        for (index, shape) in slp.shapes.iter().enumerate() {
            texture_builder = texture_builder.blit_shape(&shape.pixels,
                                                         Rect::of(0,
                                                                  0,
                                                                  shape.header.width as i32,
                                                                  shape.header.height as i32),
                                                         dst_rects[index]);
        }

        Ok(Shape {
            texture: try!(texture_builder.build(renderer)),
            frames: dst_rects,
            centers: centers,
        })
    }

    pub fn render_frame(&self,
                        renderer: &mut Renderer,
                        frame: usize,
                        position: &Vector2<i32>,
                        flip_horizontal: bool,
                        flip_vertical: bool) {
        let src_rect = self.frames[frame];
        let center = &self.centers[frame];

        let mut dst_rect = Rect::of(0, 0, src_rect.w, src_rect.h);
        dst_rect.translate(position.x, position.y);

        // Need to mirror the center offset if flipping
        let (mut offset_x, mut offset_y) = (center.x, center.y);
        if flip_horizontal {
            offset_x = src_rect.w - offset_x;
        }
        if flip_vertical {
            offset_y = src_rect.h - offset_y;
        }
        dst_rect.translate(-offset_x, -offset_y);

        renderer.render_texture(&self.texture,
                                Some(src_rect.into()),
                                dst_rect.into(),
                                flip_horizontal,
                                flip_vertical);
    }
}

enum ShapeCache {
    Cached(Shape),
    Failed,
}

pub struct ShapeManager {
    drs_manager: DrsManagerRef,
    shapes: HashMap<ShapeKey, ShapeCache>,
    palette: Vec<u32>,
}

pub type ShapeManagerRef = Rc<RefCell<ShapeManager>>;

impl ShapeManager {
    pub fn new(drs_manager: DrsManagerRef) -> Result<ShapeManagerRef> {
        let palette = {
                let borrowed_drs = drs_manager.borrow();
                let interfac = borrowed_drs.get(DrsKey::Interfac);
                let bin_table = try!(interfac.find_table(DrsFileType::Binary)
                    .ok_or(ErrorKind::InterfacBinaryTableMissing));
                let palette_contents = &try!(bin_table.find_file_contents(PALETTE_FILE_ID)
                    .ok_or(ErrorKind::InterfacMissingPalette));
                try!(palette::read_from(&mut io::Cursor::new(palette_contents)))
            }
            .iter()
            .map(|c: &PaletteColor| -> u32 { (*c).into() })
            .collect();

        Ok(Rc::new(RefCell::new(ShapeManager {
            drs_manager: drs_manager,
            shapes: HashMap::new(),
            palette: palette,
        })))
    }

    pub fn get<'a>(&'a mut self, shape_key: &ShapeKey, renderer: &mut Renderer) -> Option<&'a Shape> {
        use self::ShapeCache::*;

        let cached = self.shapes.get(&shape_key).is_some();
        if !cached {
            match self.load_shape(shape_key, renderer) {
                Ok(shape) => {
                    self.shapes.insert(*shape_key, Cached(shape));
                }
                Err(err) => {
                    self.shapes.insert(*shape_key, Failed);
                    println!("Failed to load shape {:?}: {}", shape_key, err);
                    return None;
                }
            };
        }

        match *self.shapes.get(&shape_key).unwrap() {
            Cached(ref shape) => return Some(shape),
            Failed => return None,
        }
    }

    fn load_shape(&self, shape_key: &ShapeKey, renderer: &mut Renderer) -> Result<Shape> {
        let borrowed_drs = self.drs_manager.borrow();
        let drs_file = borrowed_drs.get(shape_key.drs_key);

        let slp_table = try!(drs_file.find_table(DrsFileType::Slp)
            .ok_or(ErrorKind::NoSlpTableInDrs(shape_key.drs_key)));
        let slp_contents = try!(slp_table.find_file_contents(*shape_key.slp_id)
            .ok_or(ErrorKind::SlpNotFound(shape_key.drs_key, *shape_key.slp_id)));

        let slp = try!(SlpFile::read_from(&mut io::Cursor::new(slp_contents), *shape_key.player_color));

        Shape::load_from(&slp, &self.palette, renderer)
    }
}
<commit_msg>Don't render a shape if its center is an extreme value (fixes #53)<commit_after>// OpenAOE: An open source reimplementation of Age of Empires (1997)
// Copyright (c) 2016 Kevin Fuller
//
// 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.

use drs::DrsFileType;
use drs_manager::{DrsKey, DrsManagerRef};
use error::*;
use identifier::{PlayerColorId, SlpFileId};
use media::{Renderer, Texture, TextureBuilder};

use nalgebra::Vector2;
use palette::{self, PaletteColor};
use slp::SlpFile;

use std::cell::RefCell;
use std::collections::HashMap;
use std::io;
use std::rc::Rc;
use types::Rect;

const SHAPE_PADDING: i32 = 4;
const PALETTE_FILE_ID: u32 = 50500;
const CENTER_CUTOFF: i32 = 100000;

#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)]
pub struct ShapeKey {
    pub drs_key: DrsKey,
    pub slp_id: SlpFileId,
    pub player_color: PlayerColorId,
}

impl ShapeKey {
    pub fn new(drs_key: DrsKey, slp_id: SlpFileId, player_color: PlayerColorId) -> ShapeKey {
        ShapeKey {
            drs_key: drs_key,
            slp_id: slp_id,
            player_color: player_color,
        }
    }
}

pub struct Shape {
    texture: Texture,
    frames: Vec<Rect>,
    centers: Vec<Vector2<i32>>,
}

impl Shape {
    fn load_from(slp: &SlpFile, palette: &[u32], renderer: &mut Renderer) -> Result<Shape> {
        let mut total_rect = Rect::new();
        let mut dst_rects = Vec::new();
        let mut centers = Vec::new();
        let mut next_x = 0i32;
        for shape in &slp.shapes {
            let dst_rect = Rect::of(next_x,
                                    0,
                                    shape.header.width as i32,
                                    shape.header.height as i32);
            dst_rects.push(dst_rect);
            centers.push(Vector2::new(shape.header.center_x, shape.header.center_y));

            total_rect.extend(&dst_rect);
            next_x += shape.header.width as i32 + SHAPE_PADDING;
        }

        let mut texture_builder =
            try!(TextureBuilder::new(total_rect.w as u32, total_rect.h as u32, &palette));
        for (index, shape) in slp.shapes.iter().enumerate() {
            texture_builder = texture_builder.blit_shape(&shape.pixels,
                                                         Rect::of(0,
                                                                  0,
                                                                  shape.header.width as i32,
                                                                  shape.header.height as i32),
                                                         dst_rects[index]);
        }

        Ok(Shape {
            texture: try!(texture_builder.build(renderer)),
            frames: dst_rects,
            centers: centers,
        })
    }

    pub fn render_frame(&self,
                        renderer: &mut Renderer,
                        frame: usize,
                        position: &Vector2<i32>,
                        flip_horizontal: bool,
                        flip_vertical: bool) {
        let src_rect = self.frames[frame];
        let center = &self.centers[frame];

        // Fixes #53: If the frame's center is an extreme value, it shouldn't be drawn
        if center.x.abs() > CENTER_CUTOFF || center.y.abs() > CENTER_CUTOFF {
            return;
        }

        let mut dst_rect = Rect::of(0, 0, src_rect.w, src_rect.h);
        dst_rect.translate(position.x, position.y);

        // Need to mirror the center offset if flipping
        let (mut offset_x, mut offset_y) = (center.x, center.y);
        if flip_horizontal {
            offset_x = src_rect.w - offset_x;
        }
        if flip_vertical {
            offset_y = src_rect.h - offset_y;
        }
        dst_rect.translate(-offset_x, -offset_y);

        renderer.render_texture(&self.texture,
                                Some(src_rect.into()),
                                dst_rect.into(),
                                flip_horizontal,
                                flip_vertical);
    }
}

enum ShapeCache {
    Cached(Shape),
    Failed,
}

pub struct ShapeManager {
    drs_manager: DrsManagerRef,
    shapes: HashMap<ShapeKey, ShapeCache>,
    palette: Vec<u32>,
}

pub type ShapeManagerRef = Rc<RefCell<ShapeManager>>;

impl ShapeManager {
    pub fn new(drs_manager: DrsManagerRef) -> Result<ShapeManagerRef> {
        let palette = {
                let borrowed_drs = drs_manager.borrow();
                let interfac = borrowed_drs.get(DrsKey::Interfac);
                let bin_table = try!(interfac.find_table(DrsFileType::Binary)
                    .ok_or(ErrorKind::InterfacBinaryTableMissing));
                let palette_contents = &try!(bin_table.find_file_contents(PALETTE_FILE_ID)
                    .ok_or(ErrorKind::InterfacMissingPalette));
                try!(palette::read_from(&mut io::Cursor::new(palette_contents)))
            }
            .iter()
            .map(|c: &PaletteColor| -> u32 { (*c).into() })
            .collect();

        Ok(Rc::new(RefCell::new(ShapeManager {
            drs_manager: drs_manager,
            shapes: HashMap::new(),
            palette: palette,
        })))
    }

    pub fn get<'a>(&'a mut self, shape_key: &ShapeKey, renderer: &mut Renderer) -> Option<&'a Shape> {
        use self::ShapeCache::*;

        let cached = self.shapes.get(&shape_key).is_some();
        if !cached {
            match self.load_shape(shape_key, renderer) {
                Ok(shape) => {
                    self.shapes.insert(*shape_key, Cached(shape));
                }
                Err(err) => {
                    self.shapes.insert(*shape_key, Failed);
                    println!("Failed to load shape {:?}: {}", shape_key, err);
                    return None;
                }
            };
        }

        match *self.shapes.get(&shape_key).unwrap() {
            Cached(ref shape) => return Some(shape),
            Failed => return None,
        }
    }

    fn load_shape(&self, shape_key: &ShapeKey, renderer: &mut Renderer) -> Result<Shape> {
        let borrowed_drs = self.drs_manager.borrow();
        let drs_file = borrowed_drs.get(shape_key.drs_key);

        let slp_table = try!(drs_file.find_table(DrsFileType::Slp)
            .ok_or(ErrorKind::NoSlpTableInDrs(shape_key.drs_key)));
        let slp_contents = try!(slp_table.find_file_contents(*shape_key.slp_id)
            .ok_or(ErrorKind::SlpNotFound(shape_key.drs_key, *shape_key.slp_id)));

        let slp = try!(SlpFile::read_from(&mut io::Cursor::new(slp_contents), *shape_key.player_color));

        Shape::load_from(&slp, &self.palette, renderer)
    }
}
<|endoftext|>


<commit_before>use crate::utils::{in_macro_or_desugar, is_expn_of, snippet_opt, span_lint_and_then};
use rustc::hir::{intravisit::FnKind, Body, ExprKind, FnDecl, HirId, MatchSource};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use syntax::source_map::Span;

declare_clippy_lint! {
    /// **What it does:** Checks for missing return statements at the end of a block.
    ///
    /// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
    /// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
    /// the last returning statement because the only difference is a missing `;`. Especially in bigger
    /// code with multiple return paths having a `return` keyword makes it easier to find the
    /// corresponding statements.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// fn foo(x: usize) {
    ///     x
    /// }
    /// ```
    /// add return
    /// ```rust
    /// fn foo(x: usize) {
    ///     return x;
    /// }
    /// ```
    pub IMPLICIT_RETURN,
    restriction,
    "use a return statement like `return expr` instead of an expression"
}

declare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]);

impl ImplicitReturn {
    fn lint(cx: &LateContext<'_, '_>, outer_span: syntax_pos::Span, inner_span: syntax_pos::Span, msg: &str) {
        span_lint_and_then(cx, IMPLICIT_RETURN, outer_span, "missing return statement", |db| {
            if let Some(snippet) = snippet_opt(cx, inner_span) {
                db.span_suggestion(
                    outer_span,
                    msg,
                    format!("return {}", snippet),
                    Applicability::MachineApplicable,
                );
            }
        });
    }

    fn expr_match(cx: &LateContext<'_, '_>, expr: &rustc::hir::Expr) {
        match &expr.node {
            // loops could be using `break` instead of `return`
            ExprKind::Block(block, ..) | ExprKind::Loop(block, ..) => {
                if let Some(expr) = &block.expr {
                    Self::expr_match(cx, expr);
                }
                // only needed in the case of `break` with `;` at the end
                else if let Some(stmt) = block.stmts.last() {
                    if let rustc::hir::StmtKind::Semi(expr, ..) = &stmt.node {
                        // make sure it's a break, otherwise we want to skip
                        if let ExprKind::Break(.., break_expr) = &expr.node {
                            if let Some(break_expr) = break_expr {
                                Self::lint(cx, expr.span, break_expr.span, "change `break` to `return` as shown");
                            }
                        }
                    }
                }
            },
            // use `return` instead of `break`
            ExprKind::Break(.., break_expr) => {
                if let Some(break_expr) = break_expr {
                    Self::lint(cx, expr.span, break_expr.span, "change `break` to `return` as shown");
                }
            },
            ExprKind::Match(.., arms, source) => {
                let check_all_arms = match source {
                    MatchSource::IfLetDesugar {
                        contains_else_clause: has_else,
                    } => *has_else,
                    _ => true,
                };

                if check_all_arms {
                    for arm in arms {
                        Self::expr_match(cx, &arm.body);
                    }
                } else {
                    Self::expr_match(cx, &arms.first().expect("if let doesn't have a single arm").body);
                }
            },
            // skip if it already has a return statement
            ExprKind::Ret(..) => (),
            // everything else is missing `return`
            _ => {
                // make sure it's not just an unreachable expression
                if is_expn_of(expr.span, "unreachable").is_none() {
                    Self::lint(cx, expr.span, expr.span, "add `return` as shown")
                }
            },
        }
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn {
    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        _: FnKind<'tcx>,
        _: &'tcx FnDecl,
        body: &'tcx Body,
        span: Span,
        _: HirId,
    ) {
        let def_id = cx.tcx.hir().body_owner_def_id(body.id());
        let mir = cx.tcx.optimized_mir(def_id);

        // checking return type through MIR, HIR is not able to determine inferred closure return types
        // make sure it's not a macro
        if !mir.return_ty().is_unit() && !in_macro_or_desugar(span) {
            Self::expr_match(cx, &body.value);
        }
    }
}
<commit_msg>Fix implicit_return docs<commit_after>use crate::utils::{in_macro_or_desugar, is_expn_of, snippet_opt, span_lint_and_then};
use rustc::hir::{intravisit::FnKind, Body, ExprKind, FnDecl, HirId, MatchSource};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use syntax::source_map::Span;

declare_clippy_lint! {
    /// **What it does:** Checks for missing return statements at the end of a block.
    ///
    /// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
    /// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
    /// the last returning statement because the only difference is a missing `;`. Especially in bigger
    /// code with multiple return paths having a `return` keyword makes it easier to find the
    /// corresponding statements.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// fn foo(x: usize) -> usize {
    ///     x
    /// }
    /// ```
    /// add return
    /// ```rust
    /// fn foo(x: usize) -> usize {
    ///     return x;
    /// }
    /// ```
    pub IMPLICIT_RETURN,
    restriction,
    "use a return statement like `return expr` instead of an expression"
}

declare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]);

impl ImplicitReturn {
    fn lint(cx: &LateContext<'_, '_>, outer_span: syntax_pos::Span, inner_span: syntax_pos::Span, msg: &str) {
        span_lint_and_then(cx, IMPLICIT_RETURN, outer_span, "missing return statement", |db| {
            if let Some(snippet) = snippet_opt(cx, inner_span) {
                db.span_suggestion(
                    outer_span,
                    msg,
                    format!("return {}", snippet),
                    Applicability::MachineApplicable,
                );
            }
        });
    }

    fn expr_match(cx: &LateContext<'_, '_>, expr: &rustc::hir::Expr) {
        match &expr.node {
            // loops could be using `break` instead of `return`
            ExprKind::Block(block, ..) | ExprKind::Loop(block, ..) => {
                if let Some(expr) = &block.expr {
                    Self::expr_match(cx, expr);
                }
                // only needed in the case of `break` with `;` at the end
                else if let Some(stmt) = block.stmts.last() {
                    if let rustc::hir::StmtKind::Semi(expr, ..) = &stmt.node {
                        // make sure it's a break, otherwise we want to skip
                        if let ExprKind::Break(.., break_expr) = &expr.node {
                            if let Some(break_expr) = break_expr {
                                Self::lint(cx, expr.span, break_expr.span, "change `break` to `return` as shown");
                            }
                        }
                    }
                }
            },
            // use `return` instead of `break`
            ExprKind::Break(.., break_expr) => {
                if let Some(break_expr) = break_expr {
                    Self::lint(cx, expr.span, break_expr.span, "change `break` to `return` as shown");
                }
            },
            ExprKind::Match(.., arms, source) => {
                let check_all_arms = match source {
                    MatchSource::IfLetDesugar {
                        contains_else_clause: has_else,
                    } => *has_else,
                    _ => true,
                };

                if check_all_arms {
                    for arm in arms {
                        Self::expr_match(cx, &arm.body);
                    }
                } else {
                    Self::expr_match(cx, &arms.first().expect("if let doesn't have a single arm").body);
                }
            },
            // skip if it already has a return statement
            ExprKind::Ret(..) => (),
            // everything else is missing `return`
            _ => {
                // make sure it's not just an unreachable expression
                if is_expn_of(expr.span, "unreachable").is_none() {
                    Self::lint(cx, expr.span, expr.span, "add `return` as shown")
                }
            },
        }
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn {
    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        _: FnKind<'tcx>,
        _: &'tcx FnDecl,
        body: &'tcx Body,
        span: Span,
        _: HirId,
    ) {
        let def_id = cx.tcx.hir().body_owner_def_id(body.id());
        let mir = cx.tcx.optimized_mir(def_id);

        // checking return type through MIR, HIR is not able to determine inferred closure return types
        // make sure it's not a macro
        if !mir.return_ty().is_unit() && !in_macro_or_desugar(span) {
            Self::expr_match(cx, &body.value);
        }
    }
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/dungeon-game/
pub fn calculate_minimum_hp(dungeon: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![-2, -3, 3], vec![-5, -10, 1], vec![10, 30, -5]])
    ); // 7
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![2, -3, 3], vec![-5, -10, 1], vec![10, 30, -5]])
    ); // 3
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![2, 3, 3], vec![-5, -10, 1], vec![10, 30, 5]])
    ); // 1
    println!("{}", calculate_minimum_hp(vec![vec![0]])); // 1
}
<commit_msg>Update problem 174<commit_after>// https://leetcode.com/problems/dungeon-game/
pub fn calculate_minimum_hp(dungeon: Vec<Vec<i32>>) -> i32 {
    fn f(dungeon: &Vec<Vec<i32>>, row: i32, col: i32, sum: i32, health: i32) -> i32 {
        let max_rows = dungeon.len() as i32;
        let max_cols = if max_rows > 0 { dungeon[0].len() } else { 0 } as i32;
        let value = &dungeon[row as usize][col as usize];
        let health = if sum + value <= 0 {
            (sum + value).abs() + 1
        } else {
            health
        };
        if row == max_rows - 1 && col == max_cols - 1 {
            return health;
        }
        let mut min = i32::MAX;
        if col + 1 < max_cols {
            let right = f(dungeon, row, col + 1, sum + value, health);
            min = min.min(right);
        }
        if row + 1 < max_rows {
            let down = f(dungeon, row + 1, col, sum + value, health);
            min = min.min(down);
        }
        min
    }

    f(&dungeon, 0, 0, 0, 1)
}

fn main() {
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![-2, -3, 3], vec![-5, -10, 1], vec![10, 30, -5]])
    ); // 7
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![2, 3, 3], vec![5, 10, 1], vec![10, 30, 5]])
    ); // 1
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![2, -3, 3], vec![-5, -10, 1], vec![10, 30, -5]])
    ); // 3
    println!(
        "{}",
        calculate_minimum_hp(vec![vec![2, 3, 3], vec![-5, -10, 1], vec![10, 30, 5]])
    ); // 1
    println!("{}", calculate_minimum_hp(vec![vec![0]])); // 1
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::canvas_data::{
    Backend, CanvasPaintState, Color, CompositionOp, DrawOptions, ExtendMode, Filter,
    GenericDrawTarget, GenericPathBuilder, GradientStop, GradientStops, Path, Pattern,
    SourceSurface, StrokeOptions, SurfaceFormat,
};
use crate::canvas_paint_thread::AntialiasMode;
use canvas_traits::canvas::*;
use cssparser::RGBA;
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
use std::marker::PhantomData;

pub struct RaqoteBackend;

impl Backend for RaqoteBackend {
    fn get_composition_op(&self, _opts: &DrawOptions) -> CompositionOp {
        unimplemented!()
    }

    fn need_to_draw_shadow(&self, _color: &Color) -> bool {
        unimplemented!()
    }

    fn size_from_pattern(&self, _rect: &Rect<f32>, _pattern: &Pattern) -> Option<Size2D<f32>> {
        unimplemented!()
    }

    fn set_shadow_color<'a>(&mut self, _color: RGBA, _state: &mut CanvasPaintState<'a>) {
        unimplemented!()
    }

    fn set_fill_style<'a>(
        &mut self,
        _style: FillOrStrokeStyle,
        _state: &mut CanvasPaintState<'a>,
        _drawtarget: &dyn GenericDrawTarget,
    ) {
        unimplemented!()
    }

    fn set_stroke_style<'a>(
        &mut self,
        _style: FillOrStrokeStyle,
        _state: &mut CanvasPaintState<'a>,
        _drawtarget: &dyn GenericDrawTarget,
    ) {
        unimplemented!()
    }

    fn set_global_composition<'a>(
        &mut self,
        _op: CompositionOrBlending,
        _state: &mut CanvasPaintState<'a>,
    ) {
        unimplemented!()
    }

    fn create_drawtarget(&self, size: Size2D<u64>) -> Box<dyn GenericDrawTarget> {
        Box::new(raqote::DrawTarget::new(
            size.width as i32,
            size.height as i32,
        ))
    }

    fn recreate_paint_state<'a>(&self, _state: &CanvasPaintState<'a>) -> CanvasPaintState<'a> {
        CanvasPaintState::new(AntialiasMode::Default)
    }
}

impl<'a> CanvasPaintState<'a> {
    pub fn new(_antialias: AntialiasMode) -> CanvasPaintState<'a> {
        let solid_src = raqote::SolidSource { r: 0, g: 0, b: 0, a: 255 };
        CanvasPaintState {
            draw_options: DrawOptions::Raqote(raqote::DrawOptions::new()),
            fill_style: Pattern::Raqote(raqote::Source::Solid(solid_src)),
            stroke_style: Pattern::Raqote(raqote::Source::Solid(solid_src)),
            stroke_opts: StrokeOptions::Raqote(Default::default(), PhantomData),
            transform: Transform2D::identity(),
            shadow_offset_x: 0.0,
            shadow_offset_y: 0.0,
            shadow_blur: 0.0,
            shadow_color: Color::Raqote(()),
        }
    }
}

impl Pattern<'_> {
    pub fn is_zero_size_gradient(&self) -> bool {
        match *self {
            Pattern::Raqote(_) => unimplemented!(),
        }
    }
    pub fn as_raqote(&self) -> &raqote::Source {
        match self {
            Pattern::Raqote(p) => p,
        }
    }
}

impl<'a> StrokeOptions<'a> {
    pub fn set_line_width(&mut self, _val: f32) {
        match self {
            StrokeOptions::Raqote(options, _) => options.width = _val,
        }
    }
    pub fn set_miter_limit(&mut self, _val: f32) {
        match self {
            StrokeOptions::Raqote(options, _) => options.miter_limit = _val,
        }
    }
    pub fn set_line_join(&mut self, _val: LineJoinStyle) {
        match self {
            StrokeOptions::Raqote(options, _) => options.join = _val.to_raqote_style(),
        }
    }
    pub fn set_line_cap(&mut self, _val: LineCapStyle) {
        match self {
            StrokeOptions::Raqote(options, _) => options.cap = _val.to_raqote_style(),
        }
    }
}

impl DrawOptions {
    pub fn set_alpha(&mut self, _val: f32) {
        match self {
            DrawOptions::Raqote(draw_options) => draw_options.alpha = _val,
        }
    }
    pub fn as_raqote(&self) -> &raqote::DrawOptions {
        match self {
            DrawOptions::Raqote(options) => options,
        }
    }
}

impl Path {
    pub fn transformed_copy_to_builder(
        &self,
        _transform: &Transform2D<f32>,
    ) -> Box<dyn GenericPathBuilder> {
        unimplemented!()
    }

    pub fn contains_point(&self, _x: f64, _y: f64, _path_transform: &Transform2D<f32>) -> bool {
        unimplemented!()
    }

    pub fn copy_to_builder(&self) -> Box<dyn GenericPathBuilder> {
        unimplemented!()
    }

    pub fn as_raqote(&self) -> &raqote::Path {
        match self {
            Path::Raqote(p) => p,
        }
    }
}

impl GenericDrawTarget for raqote::DrawTarget {
    fn clear_rect(&self, _rect: &Rect<f32>) {
        unimplemented!();
    }
    fn copy_surface(
        &mut self,
        _surface: SourceSurface,
        _source: Rect<i32>,
        _destination: Point2D<i32>,
    ) {
        unimplemented!();
    }
    fn create_gradient_stops(
        &self,
        _gradient_stops: Vec<GradientStop>,
        _extend_mode: ExtendMode,
    ) -> GradientStops {
        unimplemented!();
    }
    fn create_path_builder(&self) -> Box<dyn GenericPathBuilder> {
        Box::new(PathBuilder::new())
    }
    fn create_similar_draw_target(
        &self,
        _size: &Size2D<i32>,
        _format: SurfaceFormat,
    ) -> Box<dyn GenericDrawTarget> {
        unimplemented!();
    }
    fn create_source_surface_from_data(
        &self,
        _data: &[u8],
        _size: Size2D<i32>,
        _stride: i32,
    ) -> Option<SourceSurface> {
        unimplemented!();
    }
    fn draw_surface(
        &self,
        _surface: SourceSurface,
        _dest: Rect<f64>,
        _source: Rect<f64>,
        _filter: Filter,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn draw_surface_with_shadow(
        &self,
        _surface: SourceSurface,
        _dest: &Point2D<f32>,
        _color: &Color,
        _offset: &Vector2D<f32>,
        _sigma: f32,
        _operator: CompositionOp,
    ) {
        unimplemented!();
    }
    fn fill(&mut self, path: &Path, pattern: Pattern, draw_options: &DrawOptions) {
        self.fill(path.as_raqote(), pattern.as_raqote(), draw_options.as_raqote());
    }
    fn fill_rect(
        &mut self,
        _rect: &Rect<f32>,
        _pattern: Pattern,
        _draw_options: Option<&DrawOptions>,
    ) {
        unimplemented!();
    }
    fn get_format(&self) -> SurfaceFormat {
        unimplemented!();
    }
    fn get_size(&self) -> Size2D<i32> {
        unimplemented!();
    }
    fn get_transform(&self) -> Transform2D<f32> {
        unimplemented!();
    }
    fn pop_clip(&mut self) {
        unimplemented!();
    }
    fn push_clip(&mut self, _path: &Path) {
        unimplemented!();
    }
    fn set_transform(&mut self, _matrix: &Transform2D<f32>) {
        unimplemented!();
    }
    fn snapshot(&self) -> SourceSurface {
        unimplemented!();
    }
    fn stroke(
        &mut self,
        _path: &Path,
        _pattern: Pattern,
        _stroke_options: &StrokeOptions,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn stroke_line(
        &mut self,
        _start: Point2D<f32>,
        _end: Point2D<f32>,
        _pattern: Pattern,
        _stroke_options: &StrokeOptions,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn stroke_rect(
        &mut self,
        _rect: &Rect<f32>,
        _pattern: Pattern,
        _stroke_options: &StrokeOptions,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn snapshot_data(&self, _f: &dyn Fn(&[u8]) -> Vec<u8>) -> Vec<u8> {
        unimplemented!();
    }
    fn snapshot_data_owned(&self) -> Vec<u8> {
        unimplemented!();
    }
}

struct PathBuilder(Option<raqote::PathBuilder>);

impl PathBuilder {
    fn new() -> PathBuilder {
        PathBuilder(Some(raqote::PathBuilder::new()))
    }
}

impl GenericPathBuilder for PathBuilder {
    fn arc(
        &mut self,
        origin: Point2D<f32>,
        radius: f32,
        start_angle: f32,
        end_angle: f32,
        _anticlockwise: bool,
    ) {
        self.0.as_mut().unwrap().arc(origin.x, origin.y, radius, start_angle, end_angle);
    }
    fn bezier_curve_to(
        &mut self,
        control_point1: &Point2D<f32>,
        control_point2: &Point2D<f32>,
        control_point3: &Point2D<f32>,
    ) {
        self.0.as_mut().unwrap().cubic_to(
            control_point1.x,
            control_point1.y,
            control_point2.x,
            control_point2.y,
            control_point3.x,
            control_point3.y,
        );
    }
    fn close(&mut self) {
        self.0.as_mut().unwrap().close();
    }
    fn ellipse(
        &mut self,
        _origin: Point2D<f32>,
        _radius_x: f32,
        _radius_y: f32,
        _rotation_angle: f32,
        _start_angle: f32,
        _end_angle: f32,
        _anticlockwise: bool,
    ) {
        unimplemented!();
    }
    fn get_current_point(&mut self) -> Point2D<f32> {
        unimplemented!();
    }
    fn line_to(&mut self, point: Point2D<f32>) {
        self.0.as_mut().unwrap().line_to(point.x, point.y);
    }
    fn move_to(&mut self, point: Point2D<f32>) {
        self.0.as_mut().unwrap().move_to(point.x, point.y);
    }
    fn quadratic_curve_to(&mut self, control_point: &Point2D<f32>, end_point: &Point2D<f32>) {
        self.0.as_mut().unwrap().quad_to(control_point.x, control_point.y, end_point.x, end_point.y);
    }
    fn finish(&mut self) -> Path {
        Path::Raqote(self.0.take().unwrap().finish())
    }
}

pub trait ToRaqoteStyle {
    type Target;

    fn to_raqote_style(self) -> Self::Target;
}

impl ToRaqoteStyle for LineJoinStyle {
    type Target = raqote::LineJoin;

    fn to_raqote_style(self) -> raqote::LineJoin {
        match self {
            LineJoinStyle::Round => raqote::LineJoin::Round,
            LineJoinStyle::Bevel => raqote::LineJoin::Bevel,
            LineJoinStyle::Miter => raqote::LineJoin::Miter,
        }
    }
}

impl ToRaqoteStyle for LineCapStyle {
    type Target = raqote::LineCap;

    fn to_raqote_style(self) -> raqote::LineCap {
        match self {
            LineCapStyle::Butt => raqote::LineCap::Butt,
            LineCapStyle::Round => raqote::LineCap::Round,
            LineCapStyle::Square => raqote::LineCap::Square,
        }
    }
}

// TODO(pylbrecht)
#[cfg(feature = "raqote_backend")]
impl Clone for Pattern<'_> {
    fn clone(&self) -> Self {
        unimplemented!();
    }
}
<commit_msg>Implement some of GenericDrawTarget's methods for raqote<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::canvas_data::{
    Backend, CanvasPaintState, Color, CompositionOp, DrawOptions, ExtendMode, Filter,
    GenericDrawTarget, GenericPathBuilder, GradientStop, GradientStops, Path, Pattern,
    SourceSurface, StrokeOptions, SurfaceFormat,
};
use crate::canvas_paint_thread::AntialiasMode;
use canvas_traits::canvas::*;
use cssparser::RGBA;
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
use std::marker::PhantomData;

pub struct RaqoteBackend;

impl Backend for RaqoteBackend {
    fn get_composition_op(&self, _opts: &DrawOptions) -> CompositionOp {
        unimplemented!()
    }

    fn need_to_draw_shadow(&self, _color: &Color) -> bool {
        unimplemented!()
    }

    fn size_from_pattern(&self, _rect: &Rect<f32>, _pattern: &Pattern) -> Option<Size2D<f32>> {
        unimplemented!()
    }

    fn set_shadow_color<'a>(&mut self, _color: RGBA, _state: &mut CanvasPaintState<'a>) {
        unimplemented!()
    }

    fn set_fill_style<'a>(
        &mut self,
        _style: FillOrStrokeStyle,
        _state: &mut CanvasPaintState<'a>,
        _drawtarget: &dyn GenericDrawTarget,
    ) {
        unimplemented!()
    }

    fn set_stroke_style<'a>(
        &mut self,
        _style: FillOrStrokeStyle,
        _state: &mut CanvasPaintState<'a>,
        _drawtarget: &dyn GenericDrawTarget,
    ) {
        unimplemented!()
    }

    fn set_global_composition<'a>(
        &mut self,
        _op: CompositionOrBlending,
        _state: &mut CanvasPaintState<'a>,
    ) {
        unimplemented!()
    }

    fn create_drawtarget(&self, size: Size2D<u64>) -> Box<dyn GenericDrawTarget> {
        Box::new(raqote::DrawTarget::new(
            size.width as i32,
            size.height as i32,
        ))
    }

    fn recreate_paint_state<'a>(&self, _state: &CanvasPaintState<'a>) -> CanvasPaintState<'a> {
        CanvasPaintState::new(AntialiasMode::Default)
    }
}

impl<'a> CanvasPaintState<'a> {
    pub fn new(_antialias: AntialiasMode) -> CanvasPaintState<'a> {
        let solid_src = raqote::SolidSource { r: 0, g: 0, b: 0, a: 255 };
        CanvasPaintState {
            draw_options: DrawOptions::Raqote(raqote::DrawOptions::new()),
            fill_style: Pattern::Raqote(raqote::Source::Solid(solid_src)),
            stroke_style: Pattern::Raqote(raqote::Source::Solid(solid_src)),
            stroke_opts: StrokeOptions::Raqote(Default::default(), PhantomData),
            transform: Transform2D::identity(),
            shadow_offset_x: 0.0,
            shadow_offset_y: 0.0,
            shadow_blur: 0.0,
            shadow_color: Color::Raqote(()),
        }
    }
}

impl Pattern<'_> {
    pub fn is_zero_size_gradient(&self) -> bool {
        match *self {
            Pattern::Raqote(_) => unimplemented!(),
        }
    }
    pub fn as_raqote(&self) -> &raqote::Source {
        match self {
            Pattern::Raqote(p) => p,
        }
    }
}

impl<'a> StrokeOptions<'a> {
    pub fn set_line_width(&mut self, _val: f32) {
        match self {
            StrokeOptions::Raqote(options, _) => options.width = _val,
        }
    }
    pub fn set_miter_limit(&mut self, _val: f32) {
        match self {
            StrokeOptions::Raqote(options, _) => options.miter_limit = _val,
        }
    }
    pub fn set_line_join(&mut self, _val: LineJoinStyle) {
        match self {
            StrokeOptions::Raqote(options, _) => options.join = _val.to_raqote_style(),
        }
    }
    pub fn set_line_cap(&mut self, _val: LineCapStyle) {
        match self {
            StrokeOptions::Raqote(options, _) => options.cap = _val.to_raqote_style(),
        }
    }
    pub fn as_raqote(&self) -> &raqote::StrokeStyle {
        match self {
            StrokeOptions::Raqote(options, _) => options,
        }
    }
}

impl DrawOptions {
    pub fn set_alpha(&mut self, _val: f32) {
        match self {
            DrawOptions::Raqote(draw_options) => draw_options.alpha = _val,
        }
    }
    pub fn as_raqote(&self) -> &raqote::DrawOptions {
        match self {
            DrawOptions::Raqote(options) => options,
        }
    }
}

impl Path {
    pub fn transformed_copy_to_builder(
        &self,
        _transform: &Transform2D<f32>,
    ) -> Box<dyn GenericPathBuilder> {
        unimplemented!()
    }

    pub fn contains_point(&self, _x: f64, _y: f64, _path_transform: &Transform2D<f32>) -> bool {
        unimplemented!()
    }

    pub fn copy_to_builder(&self) -> Box<dyn GenericPathBuilder> {
        unimplemented!()
    }

    pub fn as_raqote(&self) -> &raqote::Path {
        match self {
            Path::Raqote(p) => p,
        }
    }
}

impl GenericDrawTarget for raqote::DrawTarget {
    fn clear_rect(&self, _rect: &Rect<f32>) {
        unimplemented!();
    }
    fn copy_surface(
        &mut self,
        _surface: SourceSurface,
        _source: Rect<i32>,
        _destination: Point2D<i32>,
    ) {
        unimplemented!();
    }
    fn create_gradient_stops(
        &self,
        _gradient_stops: Vec<GradientStop>,
        _extend_mode: ExtendMode,
    ) -> GradientStops {
        unimplemented!();
    }
    fn create_path_builder(&self) -> Box<dyn GenericPathBuilder> {
        Box::new(PathBuilder::new())
    }
    fn create_similar_draw_target(
        &self,
        _size: &Size2D<i32>,
        _format: SurfaceFormat,
    ) -> Box<dyn GenericDrawTarget> {
        unimplemented!();
    }
    fn create_source_surface_from_data(
        &self,
        _data: &[u8],
        _size: Size2D<i32>,
        _stride: i32,
    ) -> Option<SourceSurface> {
        unimplemented!();
    }
    fn draw_surface(
        &self,
        _surface: SourceSurface,
        _dest: Rect<f64>,
        _source: Rect<f64>,
        _filter: Filter,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn draw_surface_with_shadow(
        &self,
        _surface: SourceSurface,
        _dest: &Point2D<f32>,
        _color: &Color,
        _offset: &Vector2D<f32>,
        _sigma: f32,
        _operator: CompositionOp,
    ) {
        unimplemented!();
    }
    fn fill(&mut self, path: &Path, pattern: Pattern, draw_options: &DrawOptions) {
        self.fill(path.as_raqote(), pattern.as_raqote(), draw_options.as_raqote());
    }
    fn fill_rect(
        &mut self,
        _rect: &Rect<f32>,
        _pattern: Pattern,
        _draw_options: Option<&DrawOptions>,
    ) {
        unimplemented!();
    }
    fn get_format(&self) -> SurfaceFormat {
        unimplemented!();
    }
    fn get_size(&self) -> Size2D<i32> {
        unimplemented!();
    }
    fn get_transform(&self) -> Transform2D<f32> {
        *self.get_transform()
    }
    fn pop_clip(&mut self) {
        self.pop_clip();
    }
    fn push_clip(&mut self, path: &Path) {
        self.push_clip(path.as_raqote());
    }
    fn set_transform(&mut self, matrix: &Transform2D<f32>) {
        self.set_transform(matrix);
    }
    fn snapshot(&self) -> SourceSurface {
        unimplemented!();
    }
    fn stroke(
        &mut self,
        path: &Path,
        pattern: Pattern,
        stroke_options: &StrokeOptions,
        draw_options: &DrawOptions,
    ) {
        self.stroke(
            path.as_raqote(),
            pattern.as_raqote(),
            stroke_options.as_raqote(),
            draw_options.as_raqote(),
            );
    }
    fn stroke_line(
        &mut self,
        _start: Point2D<f32>,
        _end: Point2D<f32>,
        _pattern: Pattern,
        _stroke_options: &StrokeOptions,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn stroke_rect(
        &mut self,
        _rect: &Rect<f32>,
        _pattern: Pattern,
        _stroke_options: &StrokeOptions,
        _draw_options: &DrawOptions,
    ) {
        unimplemented!();
    }
    fn snapshot_data(&self, _f: &dyn Fn(&[u8]) -> Vec<u8>) -> Vec<u8> {
        unimplemented!();
    }
    fn snapshot_data_owned(&self) -> Vec<u8> {
        unimplemented!();
    }
}

struct PathBuilder(Option<raqote::PathBuilder>);

impl PathBuilder {
    fn new() -> PathBuilder {
        PathBuilder(Some(raqote::PathBuilder::new()))
    }
}

impl GenericPathBuilder for PathBuilder {
    fn arc(
        &mut self,
        origin: Point2D<f32>,
        radius: f32,
        start_angle: f32,
        end_angle: f32,
        _anticlockwise: bool,
    ) {
        self.0.as_mut().unwrap().arc(origin.x, origin.y, radius, start_angle, end_angle);
    }
    fn bezier_curve_to(
        &mut self,
        control_point1: &Point2D<f32>,
        control_point2: &Point2D<f32>,
        control_point3: &Point2D<f32>,
    ) {
        self.0.as_mut().unwrap().cubic_to(
            control_point1.x,
            control_point1.y,
            control_point2.x,
            control_point2.y,
            control_point3.x,
            control_point3.y,
        );
    }
    fn close(&mut self) {
        self.0.as_mut().unwrap().close();
    }
    fn ellipse(
        &mut self,
        _origin: Point2D<f32>,
        _radius_x: f32,
        _radius_y: f32,
        _rotation_angle: f32,
        _start_angle: f32,
        _end_angle: f32,
        _anticlockwise: bool,
    ) {
        unimplemented!();
    }
    fn get_current_point(&mut self) -> Point2D<f32> {
        unimplemented!();
    }
    fn line_to(&mut self, point: Point2D<f32>) {
        self.0.as_mut().unwrap().line_to(point.x, point.y);
    }
    fn move_to(&mut self, point: Point2D<f32>) {
        self.0.as_mut().unwrap().move_to(point.x, point.y);
    }
    fn quadratic_curve_to(&mut self, control_point: &Point2D<f32>, end_point: &Point2D<f32>) {
        self.0.as_mut().unwrap().quad_to(control_point.x, control_point.y, end_point.x, end_point.y);
    }
    fn finish(&mut self) -> Path {
        Path::Raqote(self.0.take().unwrap().finish())
    }
}

pub trait ToRaqoteStyle {
    type Target;

    fn to_raqote_style(self) -> Self::Target;
}

impl ToRaqoteStyle for LineJoinStyle {
    type Target = raqote::LineJoin;

    fn to_raqote_style(self) -> raqote::LineJoin {
        match self {
            LineJoinStyle::Round => raqote::LineJoin::Round,
            LineJoinStyle::Bevel => raqote::LineJoin::Bevel,
            LineJoinStyle::Miter => raqote::LineJoin::Miter,
        }
    }
}

impl ToRaqoteStyle for LineCapStyle {
    type Target = raqote::LineCap;

    fn to_raqote_style(self) -> raqote::LineCap {
        match self {
            LineCapStyle::Butt => raqote::LineCap::Butt,
            LineCapStyle::Round => raqote::LineCap::Round,
            LineCapStyle::Square => raqote::LineCap::Square,
        }
    }
}

// TODO(pylbrecht)
#[cfg(feature = "raqote_backend")]
impl Clone for Pattern<'_> {
    fn clone(&self) -> Self {
        unimplemented!();
    }
}
<|endoftext|>


<commit_before><commit_msg>Document rand module with more emphasis on cryptographic security<commit_after><|endoftext|>


<commit_before>use crate::raw::{Env, Local};
use crate::napi::bindings as napi;

/// Return true if an `napi_value` `val` has the expected value type.
unsafe fn is_type(env: Env, val: Local, expect: napi::ValueType) -> bool {
    let mut actual = napi::ValueType::Undefined;
    assert_eq!(napi::typeof_value(env, val, &mut actual as *mut _), napi::Status::Ok);
    actual == expect
}

pub unsafe extern "C" fn is_undefined(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Undefined)
}

pub unsafe extern "C" fn is_null(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Null)
}

/// Is `val` a JavaScript number?
pub unsafe extern "C" fn is_number(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Number)
}

/// Is `val` a JavaScript boolean?
pub unsafe extern "C" fn is_boolean(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Boolean)
}

/// Is `val` a JavaScript string?
pub unsafe extern "C" fn is_string(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::String)
}

pub unsafe extern "C" fn is_object(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Object)
}

pub unsafe extern "C" fn is_array(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_array(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

pub unsafe extern "C" fn is_function(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Function)
}

pub unsafe extern "C" fn is_error(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_error(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

/// Is `val` a Node.js Buffer instance?
pub unsafe extern "C" fn is_buffer(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_buffer(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

/// Is `val` an ArrayBuffer instance?
pub unsafe extern "C" fn is_arraybuffer(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_arraybuffer(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

pub unsafe extern "C" fn is_date(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_date(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}
<commit_msg>fix: gate is_date api behind napi-5 feature flag<commit_after>use crate::raw::{Env, Local};
use crate::napi::bindings as napi;

/// Return true if an `napi_value` `val` has the expected value type.
unsafe fn is_type(env: Env, val: Local, expect: napi::ValueType) -> bool {
    let mut actual = napi::ValueType::Undefined;
    assert_eq!(napi::typeof_value(env, val, &mut actual as *mut _), napi::Status::Ok);
    actual == expect
}

pub unsafe extern "C" fn is_undefined(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Undefined)
}

pub unsafe extern "C" fn is_null(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Null)
}

/// Is `val` a JavaScript number?
pub unsafe extern "C" fn is_number(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Number)
}

/// Is `val` a JavaScript boolean?
pub unsafe extern "C" fn is_boolean(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Boolean)
}

/// Is `val` a JavaScript string?
pub unsafe extern "C" fn is_string(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::String)
}

pub unsafe extern "C" fn is_object(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Object)
}

pub unsafe extern "C" fn is_array(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_array(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

pub unsafe extern "C" fn is_function(env: Env, val: Local) -> bool {
    is_type(env, val, napi::ValueType::Function)
}

pub unsafe extern "C" fn is_error(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_error(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

/// Is `val` a Node.js Buffer instance?
pub unsafe extern "C" fn is_buffer(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_buffer(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

/// Is `val` an ArrayBuffer instance?
pub unsafe extern "C" fn is_arraybuffer(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_arraybuffer(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}

#[cfg(feature = "napi-5")]
pub unsafe extern "C" fn is_date(env: Env, val: Local) -> bool {
    let mut result = false;
    assert_eq!(napi::is_date(env, val, &mut result as *mut _), napi::Status::Ok);
    result
}
<|endoftext|>


<commit_before>//! Loads "sysroot" crate.
//!
//! One confusing point here is that normally sysroot is a bunch of `.rlib`s,
//! but we can't process `.rlib` and need source code instead. The source code
//! is typically installed with `rustup component add rust-src` command.

use std::{convert::TryFrom, env, ops, path::PathBuf, process::Command};

use anyhow::{format_err, Result};
use arena::{Arena, Idx};
use paths::{AbsPath, AbsPathBuf};

use crate::utf8_stdout;

#[derive(Default, Debug, Clone, Eq, PartialEq)]
pub struct Sysroot {
    crates: Arena<SysrootCrateData>,
}

pub type SysrootCrate = Idx<SysrootCrateData>;

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct SysrootCrateData {
    pub name: String,
    pub root: AbsPathBuf,
    pub deps: Vec<SysrootCrate>,
}

impl ops::Index<SysrootCrate> for Sysroot {
    type Output = SysrootCrateData;
    fn index(&self, index: SysrootCrate) -> &SysrootCrateData {
        &self.crates[index]
    }
}

impl Sysroot {
    pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ {
        // core is added as a dependency before std in order to
        // mimic rustcs dependency order
        vec!["core", "alloc", "std"].into_iter().filter_map(move |it| Some((it, self.by_name(it)?)))
    }

    pub fn proc_macro(&self) -> Option<SysrootCrate> {
        self.by_name("proc_macro")
    }

    pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a {
        self.crates.iter().map(|(id, _data)| id)
    }

    pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
        log::debug!("Discovering sysroot for {}", cargo_toml.display());
        let current_dir = cargo_toml.parent().unwrap();
        let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?;
        let res = Sysroot::load(&sysroot_src_dir)?;
        Ok(res)
    }

    pub fn load(sysroot_src_dir: &AbsPath) -> Result<Sysroot> {
        let mut sysroot = Sysroot { crates: Arena::default() };

        for name in SYSROOT_CRATES.trim().lines() {
            // FIXME: first path when 1.47 comes out
            // https://github.com/rust-lang/rust/pull/73265
            let root = [format!("lib{}/lib.rs", name), format!("{}/src/lib.rs", name)]
                .iter()
                .map(|it| sysroot_src_dir.join(it))
                .find(|it| it.exists());

            if let Some(root) = root {
                sysroot.crates.alloc(SysrootCrateData {
                    name: name.into(),
                    root,
                    deps: Vec::new(),
                });
            }
        }

        if let Some(std) = sysroot.by_name("std") {
            for dep in STD_DEPS.trim().lines() {
                if let Some(dep) = sysroot.by_name(dep) {
                    sysroot.crates[std].deps.push(dep)
                }
            }
        }

        if let Some(alloc) = sysroot.by_name("alloc") {
            if let Some(core) = sysroot.by_name("core") {
                sysroot.crates[alloc].deps.push(core);
            }
        }

        if sysroot.by_name("core").is_none() {
            let var_note = if env::var_os("RUST_SRC_PATH").is_some() {
                " (`RUST_SRC_PATH` might be incorrect, try unsetting it)"
            } else {
                ""
            };
            anyhow::bail!(
                "could not find libcore in sysroot path `{}`{}",
                sysroot_src_dir.as_ref().display(),
                var_note,
            );
        }

        Ok(sysroot)
    }

    fn by_name(&self, name: &str) -> Option<SysrootCrate> {
        let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?;
        Some(id)
    }
}

fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> {
    if let Ok(path) = env::var("RUST_SRC_PATH") {
        let path = AbsPathBuf::try_from(path.as_str())
            .map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?;
        log::debug!("Discovered sysroot by RUST_SRC_PATH: {}", path.display());
        return Ok(path);
    }

    let sysroot_path = {
        let mut rustc = Command::new(toolchain::rustc());
        rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
        log::debug!("Discovering sysroot by {:?}", rustc);
        let stdout = utf8_stdout(rustc)?;
        AbsPathBuf::assert(PathBuf::from(stdout))
    };

    get_rust_src(&sysroot_path)
        .or_else(|| {
            let mut rustup = Command::new(toolchain::rustup());
            rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
            utf8_stdout(rustup).ok()?;
            get_rust_src(&sysroot_path)
        })
        .ok_or_else(|| {
            format_err!(
                "\
can't load standard library from sysroot
{}
(discovered via `rustc --print sysroot`)
try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
                sysroot_path.display(),
            )
        })
}

fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
    // Try the new path first since the old one still exists.
    //
    // FIXME: remove `src` when 1.47 comes out
    // https://github.com/rust-lang/rust/pull/73265
    let rust_src = sysroot_path.join("lib/rustlib/src/rust");
    log::debug!("Checking sysroot (looking for `library` and `src` dirs): {}", rust_src.display());
    ["library", "src"].iter().map(|it| rust_src.join(it)).find(|it| it.exists())
}

impl SysrootCrateData {
    pub fn root_dir(&self) -> &AbsPath {
        self.root.parent().unwrap()
    }
}

const SYSROOT_CRATES: &str = "
alloc
core
panic_abort
panic_unwind
proc_macro
profiler_builtins
rtstartup
std
stdarch
term
test
unwind";

const STD_DEPS: &str = "
alloc
core
panic_abort
panic_unwind
profiler_builtins
rtstartup
proc_macro
stdarch
term
test
unwind";
<commit_msg>remove FIXME after rust 1.47 comes out<commit_after>//! Loads "sysroot" crate.
//!
//! One confusing point here is that normally sysroot is a bunch of `.rlib`s,
//! but we can't process `.rlib` and need source code instead. The source code
//! is typically installed with `rustup component add rust-src` command.

use std::{convert::TryFrom, env, ops, path::PathBuf, process::Command};

use anyhow::{format_err, Result};
use arena::{Arena, Idx};
use paths::{AbsPath, AbsPathBuf};

use crate::utf8_stdout;

#[derive(Default, Debug, Clone, Eq, PartialEq)]
pub struct Sysroot {
    crates: Arena<SysrootCrateData>,
}

pub type SysrootCrate = Idx<SysrootCrateData>;

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct SysrootCrateData {
    pub name: String,
    pub root: AbsPathBuf,
    pub deps: Vec<SysrootCrate>,
}

impl ops::Index<SysrootCrate> for Sysroot {
    type Output = SysrootCrateData;
    fn index(&self, index: SysrootCrate) -> &SysrootCrateData {
        &self.crates[index]
    }
}

impl Sysroot {
    pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ {
        // core is added as a dependency before std in order to
        // mimic rustcs dependency order
        vec!["core", "alloc", "std"].into_iter().filter_map(move |it| Some((it, self.by_name(it)?)))
    }

    pub fn proc_macro(&self) -> Option<SysrootCrate> {
        self.by_name("proc_macro")
    }

    pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a {
        self.crates.iter().map(|(id, _data)| id)
    }

    pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
        log::debug!("Discovering sysroot for {}", cargo_toml.display());
        let current_dir = cargo_toml.parent().unwrap();
        let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?;
        let res = Sysroot::load(&sysroot_src_dir)?;
        Ok(res)
    }

    pub fn load(sysroot_src_dir: &AbsPath) -> Result<Sysroot> {
        let mut sysroot = Sysroot { crates: Arena::default() };

        for name in SYSROOT_CRATES.trim().lines() {
            let root = [format!("{}/src/lib.rs", name), format!("lib{}/lib.rs", name)]
                .iter()
                .map(|it| sysroot_src_dir.join(it))
                .find(|it| it.exists());

            if let Some(root) = root {
                sysroot.crates.alloc(SysrootCrateData {
                    name: name.into(),
                    root,
                    deps: Vec::new(),
                });
            }
        }

        if let Some(std) = sysroot.by_name("std") {
            for dep in STD_DEPS.trim().lines() {
                if let Some(dep) = sysroot.by_name(dep) {
                    sysroot.crates[std].deps.push(dep)
                }
            }
        }

        if let Some(alloc) = sysroot.by_name("alloc") {
            if let Some(core) = sysroot.by_name("core") {
                sysroot.crates[alloc].deps.push(core);
            }
        }

        if sysroot.by_name("core").is_none() {
            let var_note = if env::var_os("RUST_SRC_PATH").is_some() {
                " (`RUST_SRC_PATH` might be incorrect, try unsetting it)"
            } else {
                ""
            };
            anyhow::bail!(
                "could not find libcore in sysroot path `{}`{}",
                sysroot_src_dir.as_ref().display(),
                var_note,
            );
        }

        Ok(sysroot)
    }

    fn by_name(&self, name: &str) -> Option<SysrootCrate> {
        let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?;
        Some(id)
    }
}

fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> {
    if let Ok(path) = env::var("RUST_SRC_PATH") {
        let path = AbsPathBuf::try_from(path.as_str())
            .map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?;
        log::debug!("Discovered sysroot by RUST_SRC_PATH: {}", path.display());
        return Ok(path);
    }

    let sysroot_path = {
        let mut rustc = Command::new(toolchain::rustc());
        rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
        log::debug!("Discovering sysroot by {:?}", rustc);
        let stdout = utf8_stdout(rustc)?;
        AbsPathBuf::assert(PathBuf::from(stdout))
    };

    get_rust_src(&sysroot_path)
        .or_else(|| {
            let mut rustup = Command::new(toolchain::rustup());
            rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
            utf8_stdout(rustup).ok()?;
            get_rust_src(&sysroot_path)
        })
        .ok_or_else(|| {
            format_err!(
                "\
can't load standard library from sysroot
{}
(discovered via `rustc --print sysroot`)
try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
                sysroot_path.display(),
            )
        })
}

fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
    // Try the new path first since the old one still exists.
    let rust_src = sysroot_path.join("lib/rustlib/src/rust");
    log::debug!("Checking sysroot (looking for `library` and `src` dirs): {}", rust_src.display());
    ["library", "src"].iter().map(|it| rust_src.join(it)).find(|it| it.exists())
}

impl SysrootCrateData {
    pub fn root_dir(&self) -> &AbsPath {
        self.root.parent().unwrap()
    }
}

const SYSROOT_CRATES: &str = "
alloc
core
panic_abort
panic_unwind
proc_macro
profiler_builtins
rtstartup
std
stdarch
term
test
unwind";

const STD_DEPS: &str = "
alloc
core
panic_abort
panic_unwind
profiler_builtins
rtstartup
proc_macro
stdarch
term
test
unwind";
<|endoftext|>


<commit_before><commit_msg>Fix argcheck to always have a null terminated error message string<commit_after><|endoftext|>


<commit_before>
// types and type aliases

pub type R = f64;

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Deg(u8);

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Dim(uint);

// constants

pub static DEFAULT_INTEGRATION_REL_ERR: R = 1e-12;
pub static DEFAULT_INTEGRATION_ABS_ERR: R = 1e-12;

// utility functions

#[inline(always)]
pub fn pow(base: R, exp: uint) -> R {
  let mut prod = 1 as R;
  let mut i = exp;
  while i != 0u {
    prod *= base;
    i -= 1;
  }
  prod
}

#[test]
fn test_pow() {
  assert_eq!(pow(2f64, 0), 1f64);
  assert_eq!(pow(2f64, 1), 2f64);
  assert_eq!(pow(2f64, 2), 4f64);
}
<commit_msg>Replaced pow impl with possibly more efficient version.<commit_after>
// types and type aliases

pub type R = f64;

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Deg(u8);

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Dim(uint);

// constants

pub static DEFAULT_INTEGRATION_REL_ERR: R = 1e-12;
pub static DEFAULT_INTEGRATION_ABS_ERR: R = 1e-12;

#[inline]
pub fn pow(radix: R, exp: uint) -> R {
  if exp == 0u { return 1 as R; }
  if radix == 0. { return 0 as R; }
  let mut prod = 1 as R;
  let mut _exp = exp;
  let mut multiplier = radix;
  while (_exp > 0u) {
    if _exp % 2u == 1u {
      prod *= multiplier;
    }
    _exp /= 2u;
    multiplier *= multiplier;
  }
 prod
}
<|endoftext|>


<commit_before>use cocoa::base::id;
use cocoa::foundation::NSString;
use metal_sys::{MTLArgument, MTLArgumentAccess, MTLArgumentType, MTLDataType};
use objc::runtime::YES;
use std::borrow::Cow;
use std::ffi::CStr;

pub struct Argument(id);

impl Argument {
    pub fn name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn access(&self) -> ArgumentAccess {
        unsafe { self.0.access().into() }
    }

    pub fn is_active(&self) -> bool {
        unsafe { self.0.active() == YES }
    }

    pub fn index(&self) -> usize {
        unsafe { self.0.index() as usize }
    }

    pub fn get_type(&self) -> ArgumentType {
        unsafe { self.0.getType().into() }
    }

    pub fn buffer_alignment(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::Buffer {
            unsafe { Some(self.0.bufferAlignment() as usize) }
        } else {
            None
        }
    }

    pub fn buffer_data_size(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::Buffer {
            unsafe { Some(self.0.bufferDataSize() as usize) }
        } else {
            None
        }
    }

    pub fn buffer_struct_type(&self) -> ! {
        unimplemented!()
    }

    pub fn texture_data_type(&self) -> ! {
        unimplemented!()
    }

    pub fn texture_type(&self) -> ! {
        unimplemented!()
    }

    pub fn threadgroup_memory_alignment(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::ThreadgroupMemory {
            unsafe { Some(self.0.threadgroupMemoryAlignment() as usize) }
        } else {
            None
        }
    }

    pub fn threadgroup_memory_data_size(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::ThreadgroupMemory {
            unsafe { Some(self.0.threadgroupMemoryDataSize() as usize) }
        } else {
            None
        }
    }
}

impl_from_into_raw!(Argument, of class "MTLArgument");

convertible_enum!{
    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
    enum ArgumentAccess : MTLArgumentAccess {
        ReadOnly => MTLArgumentAccessReadOnly,
        ReadWrite => MTLArgumentAccessReadWrite,
        WriteOnly => MTLArgumentAccessWriteOnly
    }
}

convertible_enum! {
    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
    enum ArgumentType : MTLArgumentType {
        Buffer => MTLArgumentTypeBuffer,
        ThreadgroupMemory => MTLArgumentTypeThreadgroupMemory,
        Texture => MTLArgumentTypeTexture,
        Sampler => MTLArgumentTypeSampler
    }
}

convertible_enum! {
    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
    enum DataType : MTLDataType {
        None => MTLDataTypeNone,
        Struct => MTLDataTypeStruct,
        Array => MTLDataTypeArray,

        Float => MTLDataTypeFloat,
        Float2 => MTLDataTypeFloat2,
        Float3 => MTLDataTypeFloat3,
        Float4 => MTLDataTypeFloat4,

        Float2x2 => MTLDataTypeFloat2x2,
        Float2x3 => MTLDataTypeFloat2x3,
        Float2x4 => MTLDataTypeFloat2x4,

        Float3x2 => MTLDataTypeFloat3x2,
        Float3x3 => MTLDataTypeFloat3x3,
        Float3x4 => MTLDataTypeFloat3x4,
        Float4x2 => MTLDataTypeFloat4x2,
        Float4x3 => MTLDataTypeFloat4x3,
        Float4x4 => MTLDataTypeFloat4x4,

        Half => MTLDataTypeHalf,
        Half2 => MTLDataTypeHalf2,
        Half3 => MTLDataTypeHalf3,
        Half4 => MTLDataTypeHalf4,

        Half2x2 => MTLDataTypeHalf2x2,
        Half2x3 => MTLDataTypeHalf2x3,
        Half2x4 => MTLDataTypeHalf2x4,

        Half3x2 => MTLDataTypeHalf3x2,
        Half3x3 => MTLDataTypeHalf3x3,
        Half3x4 => MTLDataTypeHalf3x4,

        Half4x2 => MTLDataTypeHalf4x2,
        Half4x3 => MTLDataTypeHalf4x3,
        Half4x4 => MTLDataTypeHalf4x4,

        Int => MTLDataTypeInt,
        Int2 => MTLDataTypeInt2,
        Int3 => MTLDataTypeInt3,
        Int4 => MTLDataTypeInt4,
        UInt => MTLDataTypeUInt,
        UInt2 => MTLDataTypeUInt2,
        UInt3 => MTLDataTypeUInt3,
        UInt4 => MTLDataTypeUInt4,

        Short => MTLDataTypeShort,
        Short2 => MTLDataTypeShort2,
        Short3 => MTLDataTypeShort3,
        Short4 => MTLDataTypeShort4,

        UShort => MTLDataTypeUShort,
        UShort2 => MTLDataTypeUShort2,
        UShort3 => MTLDataTypeUShort3,
        UShort4 => MTLDataTypeUShort4,

        Char => MTLDataTypeChar,
        Char2 => MTLDataTypeChar2,
        Char3 => MTLDataTypeChar3,
        Char4 => MTLDataTypeChar4,

        UChar => MTLDataTypeUChar,
        UChar2 => MTLDataTypeUChar2,
        UChar3 => MTLDataTypeUChar3,
        UChar4 => MTLDataTypeUChar4,

        Bool => MTLDataTypeBool,
        Bool2 => MTLDataTypeBool2,
        Bool3 => MTLDataTypeBool3,
        Bool4 => MTLDataTypeBool4
    }
}
<commit_msg>Flesh out more methods<commit_after>use cocoa::base::id;
use cocoa::foundation::NSString;
use metal_sys::{MTLArgument, MTLArgumentAccess, MTLArgumentType, MTLDataType};
use objc::runtime::YES;
use std::borrow::Cow;
use std::ffi::CStr;
use {FromRaw, StructType};

pub struct Argument(id);

impl Argument {
    pub fn name(&self) -> Cow<str> {
        unsafe { CStr::from_ptr(self.0.name().UTF8String()).to_string_lossy() }
    }

    pub fn access(&self) -> ArgumentAccess {
        unsafe { self.0.access().into() }
    }

    pub fn is_active(&self) -> bool {
        unsafe { self.0.active() == YES }
    }

    pub fn index(&self) -> usize {
        unsafe { self.0.index() as usize }
    }

    pub fn get_type(&self) -> ArgumentType {
        unsafe { self.0.getType().into() }
    }

    pub fn buffer_alignment(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::Buffer {
            unsafe { Some(self.0.bufferAlignment() as usize) }
        } else {
            None
        }
    }

    pub fn buffer_data_size(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::Buffer {
            unsafe { Some(self.0.bufferDataSize() as usize) }
        } else {
            None
        }
    }

    pub fn buffer_data_type(&self) -> Option<DataType> {
        if self.get_type() == ArgumentType::Buffer {
            unsafe { Some(self.0.bufferDataType().into()) }
        } else {
            None
        }
    }

    pub fn buffer_struct_type(&self) -> Option<StructType> {
        if self.get_type() == ArgumentType::Buffer {
            let struct_type = unsafe { self.0.bufferStructType() };
            StructType::from_raw(struct_type).ok()
        } else {
            None
        }
    }

    pub fn texture_data_type(&self) -> Option<DataType> {
        if self.get_type() == ArgumentType::Texture {
            unsafe { Some(self.0.textureDataType().into()) }
        } else {
            None
        }
    }

    pub fn texture_type(&self) -> ! {
        unimplemented!()
    }

    pub fn threadgroup_memory_alignment(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::ThreadgroupMemory {
            unsafe { Some(self.0.threadgroupMemoryAlignment() as usize) }
        } else {
            None
        }
    }

    pub fn threadgroup_memory_data_size(&self) -> Option<usize> {
        if self.get_type() == ArgumentType::ThreadgroupMemory {
            unsafe { Some(self.0.threadgroupMemoryDataSize() as usize) }
        } else {
            None
        }
    }
}

impl_from_into_raw!(Argument, of class "MTLArgument");

convertible_enum!{
    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
    enum ArgumentAccess : MTLArgumentAccess {
        ReadOnly => MTLArgumentAccessReadOnly,
        ReadWrite => MTLArgumentAccessReadWrite,
        WriteOnly => MTLArgumentAccessWriteOnly
    }
}

convertible_enum! {
    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
    enum ArgumentType : MTLArgumentType {
        Buffer => MTLArgumentTypeBuffer,
        ThreadgroupMemory => MTLArgumentTypeThreadgroupMemory,
        Texture => MTLArgumentTypeTexture,
        Sampler => MTLArgumentTypeSampler
    }
}

convertible_enum! {
    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
    enum DataType : MTLDataType {
        None => MTLDataTypeNone,
        Struct => MTLDataTypeStruct,
        Array => MTLDataTypeArray,

        Float => MTLDataTypeFloat,
        Float2 => MTLDataTypeFloat2,
        Float3 => MTLDataTypeFloat3,
        Float4 => MTLDataTypeFloat4,

        Float2x2 => MTLDataTypeFloat2x2,
        Float2x3 => MTLDataTypeFloat2x3,
        Float2x4 => MTLDataTypeFloat2x4,

        Float3x2 => MTLDataTypeFloat3x2,
        Float3x3 => MTLDataTypeFloat3x3,
        Float3x4 => MTLDataTypeFloat3x4,
        Float4x2 => MTLDataTypeFloat4x2,
        Float4x3 => MTLDataTypeFloat4x3,
        Float4x4 => MTLDataTypeFloat4x4,

        Half => MTLDataTypeHalf,
        Half2 => MTLDataTypeHalf2,
        Half3 => MTLDataTypeHalf3,
        Half4 => MTLDataTypeHalf4,

        Half2x2 => MTLDataTypeHalf2x2,
        Half2x3 => MTLDataTypeHalf2x3,
        Half2x4 => MTLDataTypeHalf2x4,

        Half3x2 => MTLDataTypeHalf3x2,
        Half3x3 => MTLDataTypeHalf3x3,
        Half3x4 => MTLDataTypeHalf3x4,

        Half4x2 => MTLDataTypeHalf4x2,
        Half4x3 => MTLDataTypeHalf4x3,
        Half4x4 => MTLDataTypeHalf4x4,

        Int => MTLDataTypeInt,
        Int2 => MTLDataTypeInt2,
        Int3 => MTLDataTypeInt3,
        Int4 => MTLDataTypeInt4,
        UInt => MTLDataTypeUInt,
        UInt2 => MTLDataTypeUInt2,
        UInt3 => MTLDataTypeUInt3,
        UInt4 => MTLDataTypeUInt4,

        Short => MTLDataTypeShort,
        Short2 => MTLDataTypeShort2,
        Short3 => MTLDataTypeShort3,
        Short4 => MTLDataTypeShort4,

        UShort => MTLDataTypeUShort,
        UShort2 => MTLDataTypeUShort2,
        UShort3 => MTLDataTypeUShort3,
        UShort4 => MTLDataTypeUShort4,

        Char => MTLDataTypeChar,
        Char2 => MTLDataTypeChar2,
        Char3 => MTLDataTypeChar3,
        Char4 => MTLDataTypeChar4,

        UChar => MTLDataTypeUChar,
        UChar2 => MTLDataTypeUChar2,
        UChar3 => MTLDataTypeUChar3,
        UChar4 => MTLDataTypeUChar4,

        Bool => MTLDataTypeBool,
        Bool2 => MTLDataTypeBool2,
        Bool3 => MTLDataTypeBool3,
        Bool4 => MTLDataTypeBool4
    }
}
<|endoftext|>