<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 http://mozilla.org/MPL/2.0/. */

extern crate app_units;
extern crate euclid;
extern crate gleam;
extern crate glutin;
extern crate webrender;
extern crate webrender_traits;

use app_units::Au;
use euclid::Point2D;
use gleam::gl;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use std::sync::Arc;
use webrender_traits::{BlobImageResult, BlobImageError, BlobImageDescriptor};
use webrender_traits::{ColorF, Epoch, GlyphInstance, ClipRegion, ImageRendering};
use webrender_traits::{ImageDescriptor, ImageData, ImageFormat, PipelineId};
use webrender_traits::{ImageKey, BlobImageData, BlobImageRenderer, RasterizedBlobImage};
use webrender_traits::{LayoutSize, LayoutPoint, LayoutRect, LayoutTransform, DeviceUintSize};

fn load_file(name: &str) -> Vec<u8> {
    let mut file = File::open(name).unwrap();
    let mut buffer = vec![];
    file.read_to_end(&mut buffer).unwrap();
    buffer
}

struct Notifier {
    window_proxy: glutin::WindowProxy,
}

impl Notifier {
    fn new(window_proxy: glutin::WindowProxy) -> Notifier {
        Notifier {
            window_proxy: window_proxy,
        }
    }
}

impl webrender_traits::RenderNotifier for Notifier {
    fn new_frame_ready(&mut self) {
        #[cfg(not(target_os = "android"))]
        self.window_proxy.wakeup_event_loop();
    }

    fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {
        #[cfg(not(target_os = "android"))]
        self.window_proxy.wakeup_event_loop();
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let res_path = if args.len() > 1 {
        Some(PathBuf::from(&args[1]))
    } else {
        None
    };

    let window = glutin::WindowBuilder::new()
                .with_title("WebRender Sample")
                .with_gl(glutin::GlRequest::GlThenGles {
                    opengl_version: (3, 2),
                    opengles_version: (3, 0)
                })
                .build()
                .unwrap();

    unsafe {
        window.make_current().ok();
    }
    // Android uses the static generator (as opposed to a global generator) at the moment
    #[cfg(not(target_os = "android"))]
    gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);

    println!("OpenGL version {}", gl::get_string(gl::VERSION));
    println!("Shader resource path: {:?}", res_path);

    let (width, height) = window.get_inner_size().unwrap();

    let opts = webrender::RendererOptions {
        resource_override_path: res_path,
        debug: true,
        precache_shaders: true,
        blob_image_renderer: Some(Box::new(FakeBlobImageRenderer::new())),
        .. Default::default()
    };

    let (mut renderer, sender) = webrender::renderer::Renderer::new(opts).unwrap();
    let api = sender.create_api();

    let notifier = Box::new(Notifier::new(window.create_window_proxy()));
    renderer.set_render_notifier(notifier);

    let epoch = Epoch(0);
    let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0);

    let vector_img = api.generate_image_key();
    api.add_image(
        vector_img,
        ImageDescriptor::new(100, 100, ImageFormat::RGBA8, true),
        ImageData::new_blob_image(Vec::new()),
        None,
    );

    let pipeline_id = PipelineId(0, 0);
    let mut builder = webrender_traits::DisplayListBuilder::new(pipeline_id);

    let bounds = LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(width as f32, height as f32));
    let clip_region = {
        let complex = webrender_traits::ComplexClipRegion::new(
            LayoutRect::new(LayoutPoint::new(50.0, 50.0), LayoutSize::new(100.0, 100.0)),
            webrender_traits::BorderRadius::uniform(20.0));

        builder.new_clip_region(&bounds, vec![complex], None)
    };

    builder.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
                                  bounds,
                                  clip_region,
                                  0,
                                  LayoutTransform::identity().into(),
                                  LayoutTransform::identity(),
                                  webrender_traits::MixBlendMode::Normal,
                                  Vec::new());
    builder.push_image(
        LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(100.0, 100.0)),
        ClipRegion::simple(&bounds),
        LayoutSize::new(100.0, 100.0),
        LayoutSize::new(0.0, 0.0),
        ImageRendering::Auto,
        vector_img,
    );

    let sub_clip = {
        let mask_image = api.generate_image_key();
        api.add_image(
            mask_image,
            ImageDescriptor::new(2, 2, ImageFormat::A8, true),
            ImageData::new(vec![0, 80, 180, 255]),
            None,
        );
        let mask = webrender_traits::ImageMask {
            image: mask_image,
            rect: LayoutRect::new(LayoutPoint::new(75.0, 75.0), LayoutSize::new(100.0, 100.0)),
            repeat: false,
        };
        let complex = webrender_traits::ComplexClipRegion::new(
            LayoutRect::new(LayoutPoint::new(50.0, 50.0), LayoutSize::new(100.0, 100.0)),
            webrender_traits::BorderRadius::uniform(20.0));

        builder.new_clip_region(&bounds, vec![complex], Some(mask))
    };

    builder.push_rect(LayoutRect::new(LayoutPoint::new(100.0, 100.0), LayoutSize::new(100.0, 100.0)),
                      sub_clip,
                      ColorF::new(0.0, 1.0, 0.0, 1.0));
    builder.push_rect(LayoutRect::new(LayoutPoint::new(250.0, 100.0), LayoutSize::new(100.0, 100.0)),
                      sub_clip,
                      ColorF::new(0.0, 1.0, 0.0, 1.0));
    let border_side = webrender_traits::BorderSide {
        color: ColorF::new(0.0, 0.0, 1.0, 1.0),
        style: webrender_traits::BorderStyle::Groove,
    };
    let border_widths = webrender_traits::BorderWidths {
        top: 10.0,
        left: 10.0,
        bottom: 10.0,
        right: 10.0,
    };
    let border_details = webrender_traits::BorderDetails::Normal(webrender_traits::NormalBorder {
        top: border_side,
        right: border_side,
        bottom: border_side,
        left: border_side,
        radius: webrender_traits::BorderRadius::uniform(20.0),
    });
    builder.push_border(LayoutRect::new(LayoutPoint::new(100.0, 100.0), LayoutSize::new(100.0, 100.0)),
                        sub_clip,
                        border_widths,
                        border_details);

    if false { // draw text?
        let font_key = api.generate_font_key();
        let font_bytes = load_file("res/FreeSans.ttf");
        api.add_raw_font(font_key, font_bytes);

        let text_bounds = LayoutRect::new(LayoutPoint::new(100.0, 200.0), LayoutSize::new(700.0, 300.0));

        let glyphs = vec![
            GlyphInstance {
                index: 48,
                point: Point2D::new(100.0, 100.0),
            },
            GlyphInstance {
                index: 68,
                point: Point2D::new(150.0, 100.0),
            },
            GlyphInstance {
                index: 80,
                point: Point2D::new(200.0, 100.0),
            },
            GlyphInstance {
                index: 82,
                point: Point2D::new(250.0, 100.0),
            },
            GlyphInstance {
                index: 81,
                point: Point2D::new(300.0, 100.0),
            },
            GlyphInstance {
                index: 3,
                point: Point2D::new(350.0, 100.0),
            },
            GlyphInstance {
                index: 86,
                point: Point2D::new(400.0, 100.0),
            },
            GlyphInstance {
                index: 79,
                point: Point2D::new(450.0, 100.0),
            },
            GlyphInstance {
                index: 72,
                point: Point2D::new(500.0, 100.0),
            },
            GlyphInstance {
                index: 83,
                point: Point2D::new(550.0, 100.0),
            },
            GlyphInstance {
                index: 87,
                point: Point2D::new(600.0, 100.0),
            },
            GlyphInstance {
                index: 17,
                point: Point2D::new(650.0, 100.0),
            },
        ];

        builder.push_text(text_bounds,
                          webrender_traits::ClipRegion::simple(&bounds),
                          glyphs,
                          font_key,
                          ColorF::new(1.0, 1.0, 0.0, 1.0),
                          Au::from_px(32),
                          Au::from_px(0),
                          None);
    }

    builder.pop_stacking_context();

    api.set_root_display_list(
        Some(root_background_color),
        epoch,
        LayoutSize::new(width as f32, height as f32),
        builder.finalize(),
        true);
    api.set_root_pipeline(pipeline_id);
    api.generate_frame(None);

    for event in window.wait_events() {
        renderer.update();

        renderer.render(DeviceUintSize::new(width, height));

        window.swap_buffers().ok();

        match event {
            glutin::Event::Closed |
            glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
            glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Q)) => break,
            _ => ()
        }
    }
}

struct FakeBlobImageRenderer {
    images: HashMap<ImageKey, BlobImageResult>,
}

impl FakeBlobImageRenderer {
    fn new() -> Self {
        FakeBlobImageRenderer { images: HashMap::new() }
    }
}

impl BlobImageRenderer for FakeBlobImageRenderer {
    fn request_blob_image(&mut self, key: ImageKey, _: Arc<BlobImageData>, descriptor: &BlobImageDescriptor) {
        let mut texels = Vec::with_capacity((descriptor.width * descriptor.height * 4) as usize);
        for y in 0..descriptor.height {
            for x in 0..descriptor.width {
                // render a simple checkerboard pattern
                let a = if (x % 20 >= 10) != (y % 20 >= 10) { 255 } else { 0 };
                match descriptor.format {
                    ImageFormat::RGBA8 => {
                        texels.push(a);
                        texels.push(a);
                        texels.push(a);
                        texels.push(255);
                    }
                    ImageFormat::A8 => {
                        texels.push(a);
                    }
                    _ => {
                        self.images.insert(key,
                            Err(BlobImageError::Other(format!(
                                "Usupported image format {:?}",
                                descriptor.format
                            )))
                        );
                        return;
                    }
                }
            }
        }

        self.images.insert(key, Ok(RasterizedBlobImage {
            data: texels,
            width: descriptor.width,
            height: descriptor.height,
        }));
    }

    fn resolve_blob_image(&mut self, key: ImageKey) -> BlobImageResult {
        self.images.remove(&key).unwrap_or(Err(BlobImageError::InvalidKey))
    }
}
<commit_msg>Auto merge of #935 - glennw:fix-725, r=mbrubeck<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 http://mozilla.org/MPL/2.0/. */

extern crate app_units;
extern crate euclid;
extern crate gleam;
extern crate glutin;
extern crate webrender;
extern crate webrender_traits;

use app_units::Au;
use euclid::Point2D;
use gleam::gl;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use std::sync::Arc;
use webrender_traits::{BlobImageResult, BlobImageError, BlobImageDescriptor};
use webrender_traits::{ColorF, Epoch, GlyphInstance, ClipRegion, ImageRendering};
use webrender_traits::{ImageDescriptor, ImageData, ImageFormat, PipelineId};
use webrender_traits::{ImageKey, BlobImageData, BlobImageRenderer, RasterizedBlobImage};
use webrender_traits::{LayoutSize, LayoutPoint, LayoutRect, LayoutTransform, DeviceUintSize};

fn load_file(name: &str) -> Vec<u8> {
    let mut file = File::open(name).unwrap();
    let mut buffer = vec![];
    file.read_to_end(&mut buffer).unwrap();
    buffer
}

struct Notifier {
    window_proxy: glutin::WindowProxy,
}

impl Notifier {
    fn new(window_proxy: glutin::WindowProxy) -> Notifier {
        Notifier {
            window_proxy: window_proxy,
        }
    }
}

impl webrender_traits::RenderNotifier for Notifier {
    fn new_frame_ready(&mut self) {
        #[cfg(not(target_os = "android"))]
        self.window_proxy.wakeup_event_loop();
    }

    fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {
        #[cfg(not(target_os = "android"))]
        self.window_proxy.wakeup_event_loop();
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let res_path = if args.len() > 1 {
        Some(PathBuf::from(&args[1]))
    } else {
        None
    };

    let window = glutin::WindowBuilder::new()
                .with_title("WebRender Sample")
                .with_gl(glutin::GlRequest::GlThenGles {
                    opengl_version: (3, 2),
                    opengles_version: (3, 0)
                })
                .build()
                .unwrap();

    unsafe {
        window.make_current().ok();
    }
    // Android uses the static generator (as opposed to a global generator) at the moment
    #[cfg(not(target_os = "android"))]
    gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);

    println!("OpenGL version {}", gl::get_string(gl::VERSION));
    println!("Shader resource path: {:?}", res_path);

    let (width, height) = window.get_inner_size().unwrap();

    let opts = webrender::RendererOptions {
        resource_override_path: res_path,
        debug: true,
        precache_shaders: true,
        blob_image_renderer: Some(Box::new(FakeBlobImageRenderer::new())),
        device_pixel_ratio: window.hidpi_factor(),
        .. Default::default()
    };

    let (mut renderer, sender) = webrender::renderer::Renderer::new(opts).unwrap();
    let api = sender.create_api();

    let notifier = Box::new(Notifier::new(window.create_window_proxy()));
    renderer.set_render_notifier(notifier);

    let epoch = Epoch(0);
    let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0);

    let vector_img = api.generate_image_key();
    api.add_image(
        vector_img,
        ImageDescriptor::new(100, 100, ImageFormat::RGBA8, true),
        ImageData::new_blob_image(Vec::new()),
        None,
    );

    let pipeline_id = PipelineId(0, 0);
    let mut builder = webrender_traits::DisplayListBuilder::new(pipeline_id);

    let bounds = LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(width as f32, height as f32));
    let clip_region = {
        let complex = webrender_traits::ComplexClipRegion::new(
            LayoutRect::new(LayoutPoint::new(50.0, 50.0), LayoutSize::new(100.0, 100.0)),
            webrender_traits::BorderRadius::uniform(20.0));

        builder.new_clip_region(&bounds, vec![complex], None)
    };

    builder.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
                                  bounds,
                                  clip_region,
                                  0,
                                  LayoutTransform::identity().into(),
                                  LayoutTransform::identity(),
                                  webrender_traits::MixBlendMode::Normal,
                                  Vec::new());
    builder.push_image(
        LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(100.0, 100.0)),
        ClipRegion::simple(&bounds),
        LayoutSize::new(100.0, 100.0),
        LayoutSize::new(0.0, 0.0),
        ImageRendering::Auto,
        vector_img,
    );

    let sub_clip = {
        let mask_image = api.generate_image_key();
        api.add_image(
            mask_image,
            ImageDescriptor::new(2, 2, ImageFormat::A8, true),
            ImageData::new(vec![0, 80, 180, 255]),
            None,
        );
        let mask = webrender_traits::ImageMask {
            image: mask_image,
            rect: LayoutRect::new(LayoutPoint::new(75.0, 75.0), LayoutSize::new(100.0, 100.0)),
            repeat: false,
        };
        let complex = webrender_traits::ComplexClipRegion::new(
            LayoutRect::new(LayoutPoint::new(50.0, 50.0), LayoutSize::new(100.0, 100.0)),
            webrender_traits::BorderRadius::uniform(20.0));

        builder.new_clip_region(&bounds, vec![complex], Some(mask))
    };

    builder.push_rect(LayoutRect::new(LayoutPoint::new(100.0, 100.0), LayoutSize::new(100.0, 100.0)),
                      sub_clip,
                      ColorF::new(0.0, 1.0, 0.0, 1.0));
    builder.push_rect(LayoutRect::new(LayoutPoint::new(250.0, 100.0), LayoutSize::new(100.0, 100.0)),
                      sub_clip,
                      ColorF::new(0.0, 1.0, 0.0, 1.0));
    let border_side = webrender_traits::BorderSide {
        color: ColorF::new(0.0, 0.0, 1.0, 1.0),
        style: webrender_traits::BorderStyle::Groove,
    };
    let border_widths = webrender_traits::BorderWidths {
        top: 10.0,
        left: 10.0,
        bottom: 10.0,
        right: 10.0,
    };
    let border_details = webrender_traits::BorderDetails::Normal(webrender_traits::NormalBorder {
        top: border_side,
        right: border_side,
        bottom: border_side,
        left: border_side,
        radius: webrender_traits::BorderRadius::uniform(20.0),
    });
    builder.push_border(LayoutRect::new(LayoutPoint::new(100.0, 100.0), LayoutSize::new(100.0, 100.0)),
                        sub_clip,
                        border_widths,
                        border_details);

    if false { // draw text?
        let font_key = api.generate_font_key();
        let font_bytes = load_file("res/FreeSans.ttf");
        api.add_raw_font(font_key, font_bytes);

        let text_bounds = LayoutRect::new(LayoutPoint::new(100.0, 200.0), LayoutSize::new(700.0, 300.0));

        let glyphs = vec![
            GlyphInstance {
                index: 48,
                point: Point2D::new(100.0, 100.0),
            },
            GlyphInstance {
                index: 68,
                point: Point2D::new(150.0, 100.0),
            },
            GlyphInstance {
                index: 80,
                point: Point2D::new(200.0, 100.0),
            },
            GlyphInstance {
                index: 82,
                point: Point2D::new(250.0, 100.0),
            },
            GlyphInstance {
                index: 81,
                point: Point2D::new(300.0, 100.0),
            },
            GlyphInstance {
                index: 3,
                point: Point2D::new(350.0, 100.0),
            },
            GlyphInstance {
                index: 86,
                point: Point2D::new(400.0, 100.0),
            },
            GlyphInstance {
                index: 79,
                point: Point2D::new(450.0, 100.0),
            },
            GlyphInstance {
                index: 72,
                point: Point2D::new(500.0, 100.0),
            },
            GlyphInstance {
                index: 83,
                point: Point2D::new(550.0, 100.0),
            },
            GlyphInstance {
                index: 87,
                point: Point2D::new(600.0, 100.0),
            },
            GlyphInstance {
                index: 17,
                point: Point2D::new(650.0, 100.0),
            },
        ];

        builder.push_text(text_bounds,
                          webrender_traits::ClipRegion::simple(&bounds),
                          glyphs,
                          font_key,
                          ColorF::new(1.0, 1.0, 0.0, 1.0),
                          Au::from_px(32),
                          Au::from_px(0),
                          None);
    }

    builder.pop_stacking_context();

    api.set_root_display_list(
        Some(root_background_color),
        epoch,
        LayoutSize::new(width as f32, height as f32),
        builder.finalize(),
        true);
    api.set_root_pipeline(pipeline_id);
    api.generate_frame(None);

    for event in window.wait_events() {
        renderer.update();

        renderer.render(DeviceUintSize::new(width, height));

        window.swap_buffers().ok();

        match event {
            glutin::Event::Closed |
            glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
            glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Q)) => break,
            _ => ()
        }
    }
}

struct FakeBlobImageRenderer {
    images: HashMap<ImageKey, BlobImageResult>,
}

impl FakeBlobImageRenderer {
    fn new() -> Self {
        FakeBlobImageRenderer { images: HashMap::new() }
    }
}

impl BlobImageRenderer for FakeBlobImageRenderer {
    fn request_blob_image(&mut self, key: ImageKey, _: Arc<BlobImageData>, descriptor: &BlobImageDescriptor) {
        let mut texels = Vec::with_capacity((descriptor.width * descriptor.height * 4) as usize);
        for y in 0..descriptor.height {
            for x in 0..descriptor.width {
                // render a simple checkerboard pattern
                let a = if (x % 20 >= 10) != (y % 20 >= 10) { 255 } else { 0 };
                match descriptor.format {
                    ImageFormat::RGBA8 => {
                        texels.push(a);
                        texels.push(a);
                        texels.push(a);
                        texels.push(255);
                    }
                    ImageFormat::A8 => {
                        texels.push(a);
                    }
                    _ => {
                        self.images.insert(key,
                            Err(BlobImageError::Other(format!(
                                "Usupported image format {:?}",
                                descriptor.format
                            )))
                        );
                        return;
                    }
                }
            }
        }

        self.images.insert(key, Ok(RasterizedBlobImage {
            data: texels,
            width: descriptor.width,
            height: descriptor.height,
        }));
    }

    fn resolve_blob_image(&mut self, key: ImageKey) -> BlobImageResult {
        self.images.remove(&key).unwrap_or(Err(BlobImageError::InvalidKey))
    }
}
<|endoftext|>


<commit_before>/* This file is part of Grust, GObject introspection bindings for Rust
 *
 * Copyright (C) 2013  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

use plumbing;
use plumbing::{GObject,GMainContext};
use types::*;
use gobject;

pub type GType = gsize;

trait ObjectType {
    fn get_type() -> GType;
}

pub struct Interface<T> {
    priv bare: plumbing::Object
}

pub struct Reference<T> {
    priv iface: Interface<T>
}

impl<T> Interface<T> {
    pub fn new_ref(&self) -> Reference<T> {
        unsafe {
            self.bare.inc_ref();
        }
        Reference { iface: Interface { bare: self.bare } }
    }

    pub fn cast<U: ObjectType>(&self) -> &'self Interface<U> { cast(self) }

    pub unsafe fn raw(&self) -> *T { self.bare.raw() as *T }
    pub unsafe fn context(&self) -> *GMainContext { self.bare.context() }
}

impl<T> Reference<T> {
    pub fn interface(&self) -> &'self Interface<T> { &self.iface }
    pub fn as_interface<U>(&self, f: &fn(&Interface<T>) -> U) -> U {
        f(&self.iface)
    }
}

#[unsafe_destructor]
impl<T> Drop for Interface<T> {
    /* Non-copyable */
    fn finalize(&self) { }
}

#[unsafe_destructor]
impl<T> Drop for Reference<T> {
    fn finalize(&self) {
        unsafe {
            self.iface.bare.dec_ref();
        }
    }
}

impl<T> Clone for Reference<T> {
    fn clone(&self) -> Reference<T> {
        self.iface.new_ref()
    }
}

pub fn cast<'r, T, U: ObjectType>(t: &'r Interface<T>) -> &'r Interface<U> {
    unsafe {
        let inst = t.bare.type_instance();
        let dest_type = ObjectType::get_type::<U>();
        if !(gobject::g_type_check_instance_is_a(inst, dest_type) as bool) {
            fail!(fmt!("invalid cast to type `%s'",
                       str::raw::from_c_str(gobject::g_type_name(dest_type))));
        }
        cast::transmute(t)
    }
}

pub unsafe fn make_interface<T>(obj: *T, ctx: *GMainContext)
                               -> Interface<T> {
    Interface {
        bare: plumbing::get_object(obj as *GObject, ctx)
    }
}

pub unsafe fn take_object<T>(obj: *T, ctx: *GMainContext)
                            -> Reference<T> {
    Reference {
        iface: Interface {
            bare: plumbing::take_object(obj as *GObject, ctx)
        }
    }
}
<commit_msg>Do a reinterpret_cast instead of transmute in object::cast<commit_after>/* This file is part of Grust, GObject introspection bindings for Rust
 *
 * Copyright (C) 2013  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

use plumbing;
use plumbing::{GObject,GMainContext};
use types::*;
use gobject;

pub type GType = gsize;

trait ObjectType {
    fn get_type() -> GType;
}

pub struct Interface<T> {
    priv bare: plumbing::Object
}

pub struct Reference<T> {
    priv iface: Interface<T>
}

impl<T> Interface<T> {
    pub fn new_ref(&self) -> Reference<T> {
        unsafe {
            self.bare.inc_ref();
        }
        Reference { iface: Interface { bare: self.bare } }
    }

    pub fn cast<U: ObjectType>(&self) -> &'self Interface<U> { cast(self) }

    pub unsafe fn raw(&self) -> *T { self.bare.raw() as *T }
    pub unsafe fn context(&self) -> *GMainContext { self.bare.context() }
}

impl<T> Reference<T> {
    pub fn interface(&self) -> &'self Interface<T> { &self.iface }
    pub fn as_interface<U>(&self, f: &fn(&Interface<T>) -> U) -> U {
        f(&self.iface)
    }
}

#[unsafe_destructor]
impl<T> Drop for Interface<T> {
    /* Non-copyable */
    fn finalize(&self) { }
}

#[unsafe_destructor]
impl<T> Drop for Reference<T> {
    fn finalize(&self) {
        unsafe {
            self.iface.bare.dec_ref();
        }
    }
}

impl<T> Clone for Reference<T> {
    fn clone(&self) -> Reference<T> {
        self.iface.new_ref()
    }
}

pub fn cast<'r, T, U: ObjectType>(t: &'r Interface<T>) -> &'r Interface<U> {
    unsafe {
        let inst = t.bare.type_instance();
        let dest_type = ObjectType::get_type::<U>();
        if !(gobject::g_type_check_instance_is_a(inst, dest_type) as bool) {
            fail!(fmt!("invalid cast to type `%s'",
                       str::raw::from_c_str(gobject::g_type_name(dest_type))));
        }
        cast::reinterpret_cast(&t)
    }
}

pub unsafe fn make_interface<T>(obj: *T, ctx: *GMainContext)
                               -> Interface<T> {
    Interface {
        bare: plumbing::get_object(obj as *GObject, ctx)
    }
}

pub unsafe fn take_object<T>(obj: *T, ctx: *GMainContext)
                            -> Reference<T> {
    Reference {
        iface: Interface {
            bare: plumbing::take_object(obj as *GObject, ctx)
        }
    }
}
<|endoftext|>


<commit_before>use crate::language::access::sym_accessible_from;
use crate::language::error::msg::SemError;
use crate::language::report_sym_shadow;
use crate::language::sem_analysis::{module_package, ModuleDefinitionId, SemAnalysis};
use crate::language::sym::{NestedSymTable, Sym};

use dora_parser::ast::{self, UsePathComponent, UsePathComponentValue, UseTargetDescriptor};
use dora_parser::interner::Name;
use dora_parser::lexer::position::Position;

use super::sem_analysis::SourceFileId;

pub fn check<'a>(sa: &SemAnalysis) {
    for use_elem in &sa.uses {
        let _ = check_use(
            sa,
            &use_elem.ast,
            use_elem.module_id,
            use_elem.file_id,
            None,
        );
    }
}

fn check_use(
    sa: &SemAnalysis,
    use_declaration: &ast::Use,
    use_module_id: ModuleDefinitionId,
    use_file_id: SourceFileId,
    namespace: Option<Sym>,
) -> Result<(), ()> {
    let (start_idx, mut previous_sym) =
        initial_module(sa, use_declaration, use_module_id, use_file_id, namespace)?;

    for (idx, component) in use_declaration
        .common_path
        .iter()
        .enumerate()
        .skip(start_idx)
    {
        if !previous_sym.is_enum() && !previous_sym.is_module() {
            let msg = SemError::ExpectedPath;
            let pos = use_declaration.common_path[idx - 1].pos;
            sa.diag.lock().report(use_file_id, pos, msg);
            return Err(());
        }

        previous_sym = process_component(sa, use_module_id, use_file_id, previous_sym, component)?;
    }

    match &use_declaration.target {
        UseTargetDescriptor::Default => {
            let last_component = use_declaration.common_path.last().expect("no component");

            let name = match last_component.value {
                UsePathComponentValue::Name(name) => name,
                _ => unreachable!(),
            };

            define_use_target(
                sa,
                use_file_id,
                last_component.pos,
                use_module_id,
                name,
                previous_sym,
            )
        }
        UseTargetDescriptor::As(target) => {
            let last_component = use_declaration.common_path.last().expect("no component");

            let name = target.name.expect("target expected");

            define_use_target(
                sa,
                use_file_id,
                last_component.pos,
                use_module_id,
                name,
                previous_sym,
            )
        }
        UseTargetDescriptor::Group(ref targets) => {
            for nested_use in targets {
                check_use(
                    sa,
                    nested_use,
                    use_module_id,
                    use_file_id,
                    Some(previous_sym.clone()),
                )?;
            }
        }
    }

    Ok(())
}

fn initial_module(
    sa: &SemAnalysis,
    use_declaration: &ast::Use,
    use_module_id: ModuleDefinitionId,
    use_file_id: SourceFileId,
    namespace: Option<Sym>,
) -> Result<(usize, Sym), ()> {
    if let Some(namespace) = namespace {
        return Ok((0, namespace));
    }

    if let Some(first_component) = use_declaration.common_path.first() {
        match first_component.value {
            UsePathComponentValue::This => Ok((1, Sym::Module(use_module_id))),
            UsePathComponentValue::Package => {
                Ok((1, Sym::Module(module_package(sa, use_module_id))))
            }
            UsePathComponentValue::Super => {
                let module = &sa.modules[use_module_id].read();
                if let Some(module_id) = module.parent_module_id {
                    Ok((1, Sym::Module(module_id)))
                } else {
                    sa.diag.lock().report(
                        use_file_id.into(),
                        first_component.pos,
                        SemError::NoSuperModule,
                    );
                    Err(())
                }
            }
            UsePathComponentValue::Name(_) => Ok((0, Sym::Module(use_module_id))),
        }
    } else {
        Err(())
    }
}

fn process_component(
    sa: &SemAnalysis,
    use_module_id: ModuleDefinitionId,
    use_file_id: SourceFileId,
    previous_sym: Sym,
    component: &UsePathComponent,
) -> Result<Sym, ()> {
    let component_name = match component.value {
        UsePathComponentValue::Name(name) => name,
        _ => unreachable!(),
    };

    match previous_sym {
        Sym::Module(module_id) => {
            let symtable = NestedSymTable::new(sa, module_id);
            let current_sym = symtable.get(component_name);

            if let Some(current_sym) = current_sym {
                if sym_accessible_from(sa, current_sym.clone(), use_module_id) {
                    Ok(current_sym)
                } else {
                    let module = &sa.modules[module_id].read();
                    let name = sa.interner.str(component_name).to_string();
                    let msg = SemError::NotAccessibleInModule(module.name(sa), name);
                    sa.diag.lock().report(use_file_id, component.pos, msg);
                    Err(())
                }
            } else {
                let module = sa.modules.idx(module_id);
                let module = module.read();
                let name = sa.interner.str(component_name).to_string();
                let module_name = module.name(sa);
                sa.diag.lock().report(
                    use_file_id,
                    component.pos,
                    SemError::UnknownIdentifierInModule(module_name, name),
                );
                Err(())
            }
        }

        Sym::Enum(enum_id) => {
            let enum_ = sa.enums[enum_id].read();

            if let Some(&variant_idx) = enum_.name_to_value.get(&component_name) {
                Ok(Sym::EnumVariant(enum_id, variant_idx as usize))
            } else {
                let name = sa.interner.str(component_name).to_string();
                sa.diag.lock().report(
                    use_file_id,
                    component.pos,
                    SemError::UnknownEnumVariant(name),
                );
                Err(())
            }
        }

        _ => unreachable!(),
    }
}

fn define_use_target(
    sa: &SemAnalysis,
    use_file_id: SourceFileId,
    use_pos: Position,
    module_id: ModuleDefinitionId,
    name: Name,
    sym: Sym,
) {
    let module = sa.modules.idx(module_id);
    let module = module.read();

    let table = module.table.clone();
    let mut table = table.write();

    if let Some(old_sym) = table.insert(name, sym) {
        report_sym_shadow(sa, name, use_file_id, use_pos, old_sym);
    }
}

#[cfg(test)]
mod tests {
    use crate::language::error::msg::SemError;
    use crate::language::tests::*;

    #[test]
    fn check_initializer() {
        ok("let a: Int32 = 0i32;");
        ok("let a: Int32 = 0i32; var b: Int32 = a + 1i32;");
        err(
            "var a: Int32 = foo;",
            pos(1, 16),
            SemError::UnknownIdentifier("foo".into()),
        );
    }

    #[test]
    fn check_type() {
        err(
            "var x: Foo = 0;",
            pos(1, 8),
            SemError::UnknownIdentifier("Foo".into()),
        );
    }

    #[test]
    fn use_module() {
        err(
            "
            use foo::bar::Foo;
            mod foo {
                mod bar {
                    class Foo
                }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_class() {
        err(
            "
            use foo::bar::Foo;
            mod foo {
                @pub mod bar {
                    class Foo
                }
            }
        ",
            pos(2, 27),
            SemError::NotAccessibleInModule("foo::bar".into(), "Foo".into()),
        );
    }

    #[test]
    fn use_fct() {
        err(
            "
            use foo::bar;
            mod foo {
                fn bar() {}
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_global() {
        err(
            "
            use foo::bar;
            mod foo {
                var bar: Int32 = 12;
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_const() {
        err(
            "
            use foo::bar;
            mod foo {
                const bar: Int32 = 12;
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_enum() {
        err(
            "
            use foo::Bar;
            @pub mod foo {
                enum Bar { A, B, C }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );
    }

    #[test]
    fn use_enum_value() {
        err(
            "
            use foo::Bar::A;
            mod foo {
                enum Bar { A, B, C }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );

        ok("
            use foo::Bar::{A, B, C};
            mod foo {
                @pub enum Bar { A, B, C }
            }
        ");
    }

    #[test]
    fn use_trait() {
        err(
            "
            use foo::Bar;
            mod foo {
                trait Bar {}
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );
    }

    #[test]
    fn use_struct() {
        ok("
            use foo::Bar;
            mod foo {
                @pub struct Bar { f: Int32 }
            }
        ");

        err(
            "
            use foo::Bar;
            mod foo {
                struct Bar { f: Int32 }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );
    }

    #[test]
    fn use_public() {
        ok("
            @pub use foo::Bar;
            @pub mod foo {
                @pub enum Bar { A, B, C }
            }
        ");
    }

    #[test]
    #[ignore]
    fn use_keyword_only() {
        err("use self;", pos(1, 1), SemError::ExpectedPath);
        err("use super;", pos(1, 1), SemError::ExpectedPath);
        err("use package;", pos(1, 1), SemError::ExpectedPath);
    }

    #[test]
    #[ignore]
    fn use_keyword_in_middle_of_path() {
        err(
            "use foo::bar::self; mod foo { @pub mod bar {} }",
            pos(1, 1),
            SemError::ExpectedPath,
        );
        err(
            "use foo::bar::super; mod foo { @pub mod bar {} }",
            pos(1, 1),
            SemError::ExpectedPath,
        );
        err(
            "use foo::bar::package; mod foo { @pub mod bar {} }",
            pos(1, 1),
            SemError::ExpectedPath,
        );
    }
}
<commit_msg>useck: improve error handling<commit_after>use crate::language::access::sym_accessible_from;
use crate::language::error::msg::SemError;
use crate::language::report_sym_shadow;
use crate::language::sem_analysis::{module_package, ModuleDefinitionId, SemAnalysis};
use crate::language::sym::{NestedSymTable, Sym};

use dora_parser::ast::{self, UsePathComponent, UsePathComponentValue, UseTargetDescriptor};
use dora_parser::interner::Name;
use dora_parser::lexer::position::Position;

use super::sem_analysis::SourceFileId;

pub fn check<'a>(sa: &SemAnalysis) {
    for use_elem in &sa.uses {
        let _ = check_use(
            sa,
            &use_elem.ast,
            use_elem.module_id,
            use_elem.file_id,
            None,
        );
    }
}

fn check_use(
    sa: &SemAnalysis,
    use_declaration: &ast::Use,
    use_module_id: ModuleDefinitionId,
    use_file_id: SourceFileId,
    namespace: Option<Sym>,
) -> Result<(), ()> {
    let (start_idx, mut previous_sym) =
        initial_module(sa, use_declaration, use_module_id, use_file_id, namespace)?;

    for (idx, component) in use_declaration
        .common_path
        .iter()
        .enumerate()
        .skip(start_idx)
    {
        if !previous_sym.is_enum() && !previous_sym.is_module() {
            let msg = SemError::ExpectedPath;
            let pos = use_declaration.common_path[idx - 1].pos;
            sa.diag.lock().report(use_file_id, pos, msg);
            return Err(());
        }

        previous_sym = process_component(sa, use_module_id, use_file_id, previous_sym, component)?;
    }

    match &use_declaration.target {
        UseTargetDescriptor::Default => {
            let last_component = use_declaration.common_path.last().expect("no component");

            let name = match last_component.value {
                UsePathComponentValue::Name(name) => name,
                UsePathComponentValue::Package
                | UsePathComponentValue::Super
                | UsePathComponentValue::This => {
                    sa.diag
                        .lock()
                        .report(use_file_id, last_component.pos, SemError::ExpectedPath);
                    return Err(());
                }
            };

            define_use_target(
                sa,
                use_file_id,
                last_component.pos,
                use_module_id,
                name,
                previous_sym,
            )
        }
        UseTargetDescriptor::As(target) => {
            let last_component = use_declaration.common_path.last().expect("no component");

            let name = target.name.expect("target expected");

            define_use_target(
                sa,
                use_file_id,
                last_component.pos,
                use_module_id,
                name,
                previous_sym,
            )
        }
        UseTargetDescriptor::Group(ref targets) => {
            for nested_use in targets {
                check_use(
                    sa,
                    nested_use,
                    use_module_id,
                    use_file_id,
                    Some(previous_sym.clone()),
                )?;
            }
        }
    }

    Ok(())
}

fn initial_module(
    sa: &SemAnalysis,
    use_declaration: &ast::Use,
    use_module_id: ModuleDefinitionId,
    use_file_id: SourceFileId,
    namespace: Option<Sym>,
) -> Result<(usize, Sym), ()> {
    if let Some(namespace) = namespace {
        return Ok((0, namespace));
    }

    if let Some(first_component) = use_declaration.common_path.first() {
        match first_component.value {
            UsePathComponentValue::This => Ok((1, Sym::Module(use_module_id))),
            UsePathComponentValue::Package => {
                Ok((1, Sym::Module(module_package(sa, use_module_id))))
            }
            UsePathComponentValue::Super => {
                let module = &sa.modules[use_module_id].read();
                if let Some(module_id) = module.parent_module_id {
                    Ok((1, Sym::Module(module_id)))
                } else {
                    sa.diag.lock().report(
                        use_file_id.into(),
                        first_component.pos,
                        SemError::NoSuperModule,
                    );
                    Err(())
                }
            }
            UsePathComponentValue::Name(_) => Ok((0, Sym::Module(use_module_id))),
        }
    } else {
        Err(())
    }
}

fn process_component(
    sa: &SemAnalysis,
    use_module_id: ModuleDefinitionId,
    use_file_id: SourceFileId,
    previous_sym: Sym,
    component: &UsePathComponent,
) -> Result<Sym, ()> {
    let component_name = match component.value {
        UsePathComponentValue::Name(name) => name,
        UsePathComponentValue::Package
        | UsePathComponentValue::Super
        | UsePathComponentValue::This => {
            sa.diag
                .lock()
                .report(use_file_id, component.pos, SemError::ExpectedPath);
            return Err(());
        }
    };

    match previous_sym {
        Sym::Module(module_id) => {
            let symtable = NestedSymTable::new(sa, module_id);
            let current_sym = symtable.get(component_name);

            if let Some(current_sym) = current_sym {
                if sym_accessible_from(sa, current_sym.clone(), use_module_id) {
                    Ok(current_sym)
                } else {
                    let module = &sa.modules[module_id].read();
                    let name = sa.interner.str(component_name).to_string();
                    let msg = SemError::NotAccessibleInModule(module.name(sa), name);
                    sa.diag.lock().report(use_file_id, component.pos, msg);
                    Err(())
                }
            } else {
                let module = sa.modules.idx(module_id);
                let module = module.read();
                let name = sa.interner.str(component_name).to_string();
                let module_name = module.name(sa);
                sa.diag.lock().report(
                    use_file_id,
                    component.pos,
                    SemError::UnknownIdentifierInModule(module_name, name),
                );
                Err(())
            }
        }

        Sym::Enum(enum_id) => {
            let enum_ = sa.enums[enum_id].read();

            if let Some(&variant_idx) = enum_.name_to_value.get(&component_name) {
                Ok(Sym::EnumVariant(enum_id, variant_idx as usize))
            } else {
                let name = sa.interner.str(component_name).to_string();
                sa.diag.lock().report(
                    use_file_id,
                    component.pos,
                    SemError::UnknownEnumVariant(name),
                );
                Err(())
            }
        }

        _ => unreachable!(),
    }
}

fn define_use_target(
    sa: &SemAnalysis,
    use_file_id: SourceFileId,
    use_pos: Position,
    module_id: ModuleDefinitionId,
    name: Name,
    sym: Sym,
) {
    let module = sa.modules.idx(module_id);
    let module = module.read();

    let table = module.table.clone();
    let mut table = table.write();

    if let Some(old_sym) = table.insert(name, sym) {
        report_sym_shadow(sa, name, use_file_id, use_pos, old_sym);
    }
}

#[cfg(test)]
mod tests {
    use crate::language::error::msg::SemError;
    use crate::language::tests::*;

    #[test]
    fn check_initializer() {
        ok("let a: Int32 = 0i32;");
        ok("let a: Int32 = 0i32; var b: Int32 = a + 1i32;");
        err(
            "var a: Int32 = foo;",
            pos(1, 16),
            SemError::UnknownIdentifier("foo".into()),
        );
    }

    #[test]
    fn check_type() {
        err(
            "var x: Foo = 0;",
            pos(1, 8),
            SemError::UnknownIdentifier("Foo".into()),
        );
    }

    #[test]
    fn use_module() {
        err(
            "
            use foo::bar::Foo;
            mod foo {
                mod bar {
                    class Foo
                }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_class() {
        err(
            "
            use foo::bar::Foo;
            mod foo {
                @pub mod bar {
                    class Foo
                }
            }
        ",
            pos(2, 27),
            SemError::NotAccessibleInModule("foo::bar".into(), "Foo".into()),
        );
    }

    #[test]
    fn use_fct() {
        err(
            "
            use foo::bar;
            mod foo {
                fn bar() {}
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_global() {
        err(
            "
            use foo::bar;
            mod foo {
                var bar: Int32 = 12;
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_const() {
        err(
            "
            use foo::bar;
            mod foo {
                const bar: Int32 = 12;
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "bar".into()),
        );
    }

    #[test]
    fn use_enum() {
        err(
            "
            use foo::Bar;
            @pub mod foo {
                enum Bar { A, B, C }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );
    }

    #[test]
    fn use_enum_value() {
        err(
            "
            use foo::Bar::A;
            mod foo {
                enum Bar { A, B, C }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );

        ok("
            use foo::Bar::{A, B, C};
            mod foo {
                @pub enum Bar { A, B, C }
            }
        ");
    }

    #[test]
    fn use_trait() {
        err(
            "
            use foo::Bar;
            mod foo {
                trait Bar {}
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );
    }

    #[test]
    fn use_struct() {
        ok("
            use foo::Bar;
            mod foo {
                @pub struct Bar { f: Int32 }
            }
        ");

        err(
            "
            use foo::Bar;
            mod foo {
                struct Bar { f: Int32 }
            }
        ",
            pos(2, 22),
            SemError::NotAccessibleInModule("foo".into(), "Bar".into()),
        );
    }

    #[test]
    fn use_public() {
        ok("
            @pub use foo::Bar;
            @pub mod foo {
                @pub enum Bar { A, B, C }
            }
        ");
    }

    #[test]
    fn use_keyword_only() {
        err("use self;", pos(1, 5), SemError::ExpectedPath);
        err("use package;", pos(1, 5), SemError::ExpectedPath);
        err("mod foo { use super; }", pos(1, 15), SemError::ExpectedPath);
    }

    #[test]
    fn use_keyword_in_path() {
        err(
            "use foo::bar::self; mod foo { @pub mod bar {} }",
            pos(1, 15),
            SemError::ExpectedPath,
        );
        err(
            "use foo::bar::super; mod foo { @pub mod bar {} }",
            pos(1, 15),
            SemError::ExpectedPath,
        );
        err(
            "use foo::bar::package; mod foo { @pub mod bar {} }",
            pos(1, 15),
            SemError::ExpectedPath,
        );
    }
}
<|endoftext|>


<commit_before>use crate::{
    core::*,
    domains::Transition,
    fa::{Approximator, VectorLFA, Parameterised, Projector},
    policies::{
        sample_probs_with_rng,
        DifferentiablePolicy,
        ParameterisedPolicy,
        FinitePolicy,
        Policy
    },
    utils::argmax_choose,
};
use rand::{rngs::ThreadRng, thread_rng, Rng};
use std::{f64, ops::AddAssign};

pub struct Gibbs<F> {
    pub fa: F,

    rng: ThreadRng,
}

fn probabilities_from_values(values: &[f64]) -> Vector<f64> {
    let mut z = 0.0;
    let ws: Vec<f64> = values
        .iter()
        .map(|v| {
            let v = v.exp();
            z += v;

            v
        })
        .collect();

    ws.iter().map(|w| (w / z).min(1e50)).collect()
}

impl<F> Gibbs<F> {
    pub fn new(fa: F) -> Self {
        Gibbs {
            fa,

            rng: thread_rng(),
        }
    }
}

impl<F> Algorithm for Gibbs<F> {}

impl<S, M: Projector<S>> Policy<S> for Gibbs<VectorLFA<M>> {
    type Action = usize;

    fn sample(&mut self, s: &S) -> usize {
        let ps = self.probabilities(s);

        sample_probs_with_rng(&mut self.rng, ps.as_slice().unwrap())
    }

    fn mpa(&mut self, s: &S) -> usize {
        let ps = self.probabilities(s);

        argmax_choose(&mut self.rng, ps.as_slice().unwrap()).1
    }

    fn probability(&mut self, input: &S, a: usize) -> f64 { self.probabilities(input)[a] }
}

impl<S, M: Projector<S>> FinitePolicy<S> for Gibbs<VectorLFA<M>> {
    fn n_actions(&self) -> usize {
        self.fa.n_outputs()
    }

    fn probabilities(&mut self, input: &S) -> Vector<f64> {
        let values = self.fa.evaluate(input).unwrap();

        probabilities_from_values(values.as_slice().unwrap())
    }
}

impl<S, M: Projector<S>> DifferentiablePolicy<S> for Gibbs<VectorLFA<M>> {
    fn grad_log(&self, input: &S, a: usize) -> Matrix<f64> {
        let phi = self.fa.projector.project(input);

        let values = self.fa.evaluate_primal(&phi).unwrap();
        let n_actions = values.len();
        let probabilities = probabilities_from_values(values.as_slice().unwrap())
            .into_shape((1, n_actions))
            .unwrap();

        let dim = self.fa.projector.dim();
        let phi = phi.expanded(self.fa.projector.dim());

        let mut grad_log = phi
            .clone()
            .into_shape((dim, 1))
            .unwrap()
            .dot(&-probabilities);
        grad_log.column_mut(a).add_assign(&phi);

        grad_log
    }
}

impl<F: Parameterised> Parameterised for Gibbs<F> {
    fn weights(&self) -> Matrix<f64> { self.fa.weights() }
}

impl<S, M: Projector<S>> ParameterisedPolicy<S> for Gibbs<VectorLFA<M>> {
    fn update(&mut self, input: &S, a: usize, error: f64) {
        let pi = self.probability(input, a);
        let grad_log = self.grad_log(input, a);

        self.fa
            .approximator
            .weights
            .scaled_add(pi * error, &grad_log);
    }

    fn update_raw(&mut self, errors: Matrix<f64>) {
        self.fa.approximator.weights.add_assign(&errors)
    }
}

#[cfg(test)]
mod tests {
    use crate::fa::{LFA, Parameterised, basis::fixed::Polynomial};
    use crate::policies::{Policy, ParameterisedPolicy};
    use super::Gibbs;

    #[test]
    fn test_sample() {
        let fa = LFA::vector_output(Polynomial::new(1, vec![(0.0, 1.0)]), 3);
        let mut p = Gibbs::new(fa);

        for _ in 0..10 {
            p.update(&vec![0.0], 0, -100.0);
            p.update(&vec![0.0], 1, 100.0);
            p.update(&vec![0.0], 2, -100.0);
        }

        assert_eq!(p.sample(&vec![0.0]), 1);
    }
}
<commit_msg>refactor(policies): remove probability weighting in Gibbs::update(.)<commit_after>use crate::{
    core::*,
    fa::{Approximator, VectorLFA, Parameterised, Projector},
    policies::{
        sample_probs_with_rng,
        DifferentiablePolicy,
        ParameterisedPolicy,
        FinitePolicy,
        Policy
    },
    utils::argmax_choose,
};
use rand::{rngs::ThreadRng, thread_rng, Rng};
use std::{f64, ops::AddAssign};

pub struct Gibbs<F> {
    pub fa: F,

    rng: ThreadRng,
}

fn probabilities_from_values(values: &[f64]) -> Vector<f64> {
    let mut z = 0.0;
    let ws: Vec<f64> = values
        .iter()
        .map(|v| {
            let v = v.exp();
            z += v;

            v
        })
        .collect();

    ws.iter().map(|w| (w / z).min(1e50)).collect()
}

impl<F> Gibbs<F> {
    pub fn new(fa: F) -> Self {
        Gibbs {
            fa,

            rng: thread_rng(),
        }
    }
}

impl<F> Algorithm for Gibbs<F> {}

impl<S, M: Projector<S>> Policy<S> for Gibbs<VectorLFA<M>> {
    type Action = usize;

    fn sample(&mut self, s: &S) -> usize {
        let ps = self.probabilities(s);

        sample_probs_with_rng(&mut self.rng, ps.as_slice().unwrap())
    }

    fn mpa(&mut self, s: &S) -> usize {
        let ps = self.probabilities(s);

        argmax_choose(&mut self.rng, ps.as_slice().unwrap()).1
    }

    fn probability(&mut self, input: &S, a: usize) -> f64 { self.probabilities(input)[a] }
}

impl<S, M: Projector<S>> FinitePolicy<S> for Gibbs<VectorLFA<M>> {
    fn n_actions(&self) -> usize {
        self.fa.n_outputs()
    }

    fn probabilities(&mut self, input: &S) -> Vector<f64> {
        let values = self.fa.evaluate(input).unwrap();

        probabilities_from_values(values.as_slice().unwrap())
    }
}

impl<S, M: Projector<S>> DifferentiablePolicy<S> for Gibbs<VectorLFA<M>> {
    fn grad_log(&self, input: &S, a: usize) -> Matrix<f64> {
        let phi = self.fa.projector.project(input);

        let values = self.fa.evaluate_primal(&phi).unwrap();
        let n_actions = values.len();
        let probabilities = probabilities_from_values(values.as_slice().unwrap())
            .into_shape((1, n_actions))
            .unwrap();

        let dim = self.fa.projector.dim();
        let phi = phi.expanded(self.fa.projector.dim());

        let mut grad_log = phi
            .clone()
            .into_shape((dim, 1))
            .unwrap()
            .dot(&-probabilities);
        grad_log.column_mut(a).add_assign(&phi);

        grad_log
    }
}

impl<F: Parameterised> Parameterised for Gibbs<F> {
    fn weights(&self) -> Matrix<f64> { self.fa.weights() }
}

impl<S, M: Projector<S>> ParameterisedPolicy<S> for Gibbs<VectorLFA<M>> {
    fn update(&mut self, input: &S, a: usize, error: f64) {
        let grad_log = self.grad_log(input, a);

        self.fa
            .approximator
            .weights
            .scaled_add(error, &grad_log);
    }

    fn update_raw(&mut self, errors: Matrix<f64>) {
        self.fa.approximator.weights.add_assign(&errors)
    }
}

#[cfg(test)]
mod tests {
    use crate::fa::{LFA, Parameterised, basis::fixed::Polynomial};
    use crate::policies::{Policy, ParameterisedPolicy};
    use super::Gibbs;

    #[test]
    fn test_sample() {
        let fa = LFA::vector_output(Polynomial::new(1, vec![(0.0, 1.0)]), 3);
        let mut p = Gibbs::new(fa);

        for _ in 0..10 {
            p.update(&vec![0.0], 0, -100.0);
            p.update(&vec![0.0], 1, 100.0);
            p.update(&vec![0.0], 2, -100.0);
        }

        assert_eq!(p.sample(&vec![0.0]), 1);
    }
}
<|endoftext|>


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

#![feature(plugin_registrar, rustc_private)]
#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
       html_root_url = "https://rust-num.github.io/num/",
       html_playground_url = "http://play.integer32.com/")]

extern crate syntax;
extern crate syntax_ext;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr, BinOpKind};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax_ext::deriving::generic::*;
use syntax_ext::deriving::generic::ty::*;
use syntax::symbol::Symbol;
use syntax::ptr::P;
use syntax::ext::base::MultiDecorator;

use rustc_plugin::Registry;

macro_rules! pathvec {
    ($($x:ident)::+) => (
        vec![ $( stringify!($x) ),+ ]
    )
}

macro_rules! path {
    ($($x:tt)*) => (
        ::syntax_ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
    )
}

macro_rules! path_local {
    ($x:ident) => (
        ::syntax_ext::deriving::generic::ty::Path::new_local(stringify!($x))
    )
}

macro_rules! pathvec_std {
    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
        let mut v = pathvec!($($rest)::+);
        if let Some(s) = $cx.crate_root {
            v.insert(0, s);
        }
        v
    })
}

pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                      span: Span,
                                      mitem: &MetaItem,
                                      item: &Annotatable,
                                      push: &mut FnMut(Annotatable))
{
    let inline = cx.meta_word(span, Symbol::intern("inline"));
    let attrs = vec!(cx.attribute(span, inline));
    let trait_def = TraitDef {
        is_unsafe: false,
        span: span,
        attributes: Vec::new(),
        path: path!(num::FromPrimitive),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        methods: vec!(
            MethodDef {
                name: "from_i64",
                is_unsafe: false,
                unify_fieldless_variants: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(i64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs.clone(),
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("i64", c, s, sub)
                })),
            },
            MethodDef {
                name: "from_u64",
                is_unsafe: false,
                unify_fieldless_variants: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(u64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs,
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("u64", c, s, sub)
                })),
            }
        ),
        associated_types: Vec::new(),
        supports_unions: false,
    };

    trait_def.expand(cx, mitem, &item, push)
}

fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    if substr.nonself_args.len() != 1 {
        cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`")
    }

    let n = &substr.nonself_args[0];

    match *substr.fields {
        StaticStruct(..) => {
            cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs");
            return cx.expr_fail(trait_span, Symbol::intern(""));
        }
        StaticEnum(enum_def, _) => {
            if enum_def.variants.is_empty() {
                cx.span_err(trait_span,
                            "`FromPrimitive` cannot be derived for enums with no variants");
                return cx.expr_fail(trait_span, Symbol::intern(""));
            }

            let mut arms = Vec::new();

            for variant in &enum_def.variants {
                match variant.node.data {
                    ast::VariantData::Unit(..) => {
                        let span = variant.span;

                        // expr for `$n == $variant as $name`
                        let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
                        let variant = cx.expr_path(path);
                        let ty = cx.ty_ident(span, cx.ident_of(name));
                        let cast = cx.expr_cast(span, variant.clone(), ty);
                        let guard = cx.expr_binary(span, BinOpKind::Eq, n.clone(), cast);

                        // expr for `Some($variant)`
                        let body = cx.expr_some(span, variant);

                        // arm for `_ if $guard => $body`
                        let arm = ast::Arm {
                            attrs: vec!(),
                            pats: vec!(cx.pat_wild(span)),
                            guard: Some(guard),
                            body: body,
                        };

                        arms.push(arm);
                    }
                    ast::VariantData::Tuple(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for \
                                    enum variants with arguments");
                        return cx.expr_fail(trait_span,
                                            Symbol::intern(""));
                    }
                    ast::VariantData::Struct(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for enums \
                                    with struct variants");
                        return cx.expr_fail(trait_span,
                                            Symbol::intern(""));
                    }
                }
            }

            // arm for `_ => None`
            let arm = ast::Arm {
                attrs: vec!(),
                pats: vec!(cx.pat_wild(trait_span)),
                guard: None,
                body: cx.expr_none(trait_span),
            };
            arms.push(arm);

            cx.expr_match(trait_span, n.clone(), arms)
        }
        _ => cx.span_bug(trait_span, "expected StaticEnum in derive(FromPrimitive)")
    }
}

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(
        Symbol::intern("derive_NumFromPrimitive"),
        MultiDecorator(Box::new(expand_deriving_from_primitive)));
}
<commit_msg>macros: add ast::Arm beginning_vert<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(plugin_registrar, rustc_private)]
#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
       html_root_url = "https://rust-num.github.io/num/",
       html_playground_url = "http://play.integer32.com/")]

extern crate syntax;
extern crate syntax_ext;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr, BinOpKind};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax_ext::deriving::generic::*;
use syntax_ext::deriving::generic::ty::*;
use syntax::symbol::Symbol;
use syntax::ptr::P;
use syntax::ext::base::MultiDecorator;

use rustc_plugin::Registry;

macro_rules! pathvec {
    ($($x:ident)::+) => (
        vec![ $( stringify!($x) ),+ ]
    )
}

macro_rules! path {
    ($($x:tt)*) => (
        ::syntax_ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
    )
}

macro_rules! path_local {
    ($x:ident) => (
        ::syntax_ext::deriving::generic::ty::Path::new_local(stringify!($x))
    )
}

macro_rules! pathvec_std {
    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
        let mut v = pathvec!($($rest)::+);
        if let Some(s) = $cx.crate_root {
            v.insert(0, s);
        }
        v
    })
}

pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                      span: Span,
                                      mitem: &MetaItem,
                                      item: &Annotatable,
                                      push: &mut FnMut(Annotatable))
{
    let inline = cx.meta_word(span, Symbol::intern("inline"));
    let attrs = vec!(cx.attribute(span, inline));
    let trait_def = TraitDef {
        is_unsafe: false,
        span: span,
        attributes: Vec::new(),
        path: path!(num::FromPrimitive),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        methods: vec!(
            MethodDef {
                name: "from_i64",
                is_unsafe: false,
                unify_fieldless_variants: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(i64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs.clone(),
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("i64", c, s, sub)
                })),
            },
            MethodDef {
                name: "from_u64",
                is_unsafe: false,
                unify_fieldless_variants: false,
                generics: LifetimeBounds::empty(),
                explicit_self: None,
                args: vec!(Literal(path_local!(u64))),
                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                           None,
                                           vec!(Box::new(Self_)),
                                           true)),
                // #[inline] liable to cause code-bloat
                attributes: attrs,
                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                    cs_from("u64", c, s, sub)
                })),
            }
        ),
        associated_types: Vec::new(),
        supports_unions: false,
    };

    trait_def.expand(cx, mitem, &item, push)
}

fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    if substr.nonself_args.len() != 1 {
        cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`")
    }

    let n = &substr.nonself_args[0];

    match *substr.fields {
        StaticStruct(..) => {
            cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs");
            return cx.expr_fail(trait_span, Symbol::intern(""));
        }
        StaticEnum(enum_def, _) => {
            if enum_def.variants.is_empty() {
                cx.span_err(trait_span,
                            "`FromPrimitive` cannot be derived for enums with no variants");
                return cx.expr_fail(trait_span, Symbol::intern(""));
            }

            let mut arms = Vec::new();

            for variant in &enum_def.variants {
                match variant.node.data {
                    ast::VariantData::Unit(..) => {
                        let span = variant.span;

                        // expr for `$n == $variant as $name`
                        let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
                        let variant = cx.expr_path(path);
                        let ty = cx.ty_ident(span, cx.ident_of(name));
                        let cast = cx.expr_cast(span, variant.clone(), ty);
                        let guard = cx.expr_binary(span, BinOpKind::Eq, n.clone(), cast);

                        // expr for `Some($variant)`
                        let body = cx.expr_some(span, variant);

                        // arm for `_ if $guard => $body`
                        let arm = ast::Arm {
                            attrs: vec!(),
                            pats: vec!(cx.pat_wild(span)),
                            guard: Some(guard),
                            body: body,
                            beginning_vert: None,
                        };

                        arms.push(arm);
                    }
                    ast::VariantData::Tuple(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for \
                                    enum variants with arguments");
                        return cx.expr_fail(trait_span,
                                            Symbol::intern(""));
                    }
                    ast::VariantData::Struct(..) => {
                        cx.span_err(trait_span,
                                    "`FromPrimitive` cannot be derived for enums \
                                    with struct variants");
                        return cx.expr_fail(trait_span,
                                            Symbol::intern(""));
                    }
                }
            }

            // arm for `_ => None`
            let arm = ast::Arm {
                attrs: vec!(),
                pats: vec!(cx.pat_wild(trait_span)),
                guard: None,
                body: cx.expr_none(trait_span),
                beginning_vert: None,
            };
            arms.push(arm);

            cx.expr_match(trait_span, n.clone(), arms)
        }
        _ => cx.span_bug(trait_span, "expected StaticEnum in derive(FromPrimitive)")
    }
}

#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(
        Symbol::intern("derive_NumFromPrimitive"),
        MultiDecorator(Box::new(expand_deriving_from_primitive)));
}
<|endoftext|>


<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use aptos_transaction_builder::aptos_stdlib;
use forge::{AptosContext, AptosTest, Result, Test};

pub struct MintTransfer;

impl Test for MintTransfer {
    fn name(&self) -> &'static str {
        "smoke-test::aptos::mint-transfer"
    }
}

#[async_trait::async_trait]
impl AptosTest for MintTransfer {
    async fn run<'t>(&self, ctx: &mut AptosContext<'t>) -> Result<()> {
        let mut account1 = ctx.random_account();
        ctx.create_user_account(account1.public_key()).await?;
        let account2 = ctx.random_account();
        ctx.create_user_account(account2.public_key()).await?;

        ctx.mint(account1.address(), 10000).await?;

        let transfer_txn =
            account1.sign_with_transaction_builder(ctx.aptos_transaction_factory().payload(
                aptos_stdlib::encode_transfer_script_function(account2.address(), 400),
            ));
        ctx.client().submit_and_wait(&transfer_txn).await?;

        // test delegation
        let txn_factory = ctx.aptos_transaction_factory();
        let delegate_txn = ctx
            .root_account()
            .sign_with_transaction_builder(txn_factory.payload(
                aptos_stdlib::encode_delegate_mint_capability_script_function(account1.address()),
            ));
        ctx.client().submit_and_wait(&delegate_txn).await?;
        let claim_txn = account1.sign_with_transaction_builder(
            txn_factory.payload(aptos_stdlib::encode_claim_mint_capability_script_function()),
        );
        ctx.client().submit_and_wait(&claim_txn).await?;
        let mint_txn = account1.sign_with_transaction_builder(txn_factory.payload(
            aptos_stdlib::encode_mint_script_function(account1.address(), 100),
        ));
        ctx.client().submit_and_wait(&mint_txn).await?;

        Ok(())
    }
}
<commit_msg>Delegate more than one mint at a time<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use aptos_transaction_builder::aptos_stdlib;
use forge::{AptosContext, AptosTest, Result, Test};

pub struct MintTransfer;

impl Test for MintTransfer {
    fn name(&self) -> &'static str {
        "smoke-test::aptos::mint-transfer"
    }
}

#[async_trait::async_trait]
impl AptosTest for MintTransfer {
    async fn run<'t>(&self, ctx: &mut AptosContext<'t>) -> Result<()> {
        let mut account1 = ctx.random_account();
        ctx.create_user_account(account1.public_key()).await?;
        let account2 = ctx.random_account();
        ctx.create_user_account(account2.public_key()).await?;

        ctx.mint(account1.address(), 10000).await?;

        let transfer_txn =
            account1.sign_with_transaction_builder(ctx.aptos_transaction_factory().payload(
                aptos_stdlib::encode_transfer_script_function(account2.address(), 400),
            ));
        ctx.client().submit_and_wait(&transfer_txn).await?;

        // test delegation
        let txn_factory = ctx.aptos_transaction_factory();
        let delegate_txn1 = ctx
            .root_account()
            .sign_with_transaction_builder(txn_factory.payload(
                aptos_stdlib::encode_delegate_mint_capability_script_function(account1.address()),
            ));
        ctx.client().submit_and_wait(&delegate_txn1).await?;

        // Test delegating more than one at a time: faucet startup stampeding herd
        let delegate_txn2 = ctx
            .root_account()
            .sign_with_transaction_builder(txn_factory.payload(
                aptos_stdlib::encode_delegate_mint_capability_script_function(account2.address()),
            ));
        ctx.client().submit_and_wait(&delegate_txn2).await?;

        let claim_txn = account1.sign_with_transaction_builder(
            txn_factory.payload(aptos_stdlib::encode_claim_mint_capability_script_function()),
        );
        ctx.client().submit_and_wait(&claim_txn).await?;
        let mint_txn = account1.sign_with_transaction_builder(txn_factory.payload(
            aptos_stdlib::encode_mint_script_function(account1.address(), 100),
        ));
        ctx.client().submit_and_wait(&mint_txn).await?;

        Ok(())
    }
}
<|endoftext|>


<commit_before>
extern crate gitlab_api as gitlab;

use std::env;
use gitlab::GitLab;
use gitlab::Pagination;

fn main() {
    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_)  => panic!("Please set environment variable 'GITLAB_TOKEN'"),
    };

    let mut gl = GitLab::new_https("gitlab.com", &token);
    // for i in 1..82 {
    //     gl.set_pagination(Pagination{page: i, per_page: 1});
    //     println!("projects: {:?}", gl.projects().unwrap());
    // }
    gl.set_pagination(Pagination{page: 1, per_page: 100});
    let _projects = gl.projects().unwrap();
    // FIXME: Project's members are private
    // for project in projects {
    //     println!("{:?}", project.path_with_namespace);
    // }
}
<commit_msg>Don't hardcode hostname, use environment variable with default to gitlab.com<commit_after>
extern crate gitlab_api as gitlab;

use std::env;
use gitlab::GitLab;
use gitlab::Pagination;

fn main() {
    let hostname = match env::var("GITLAB_HOSTNAME") {
        Ok(val) => val,
        Err(_)  => {
            let default = String::from("gitlab.com");
            println!("Please set environment variable 'GITLAB_HOSTNAME'. Using default '{}'.", default);
            default
        },
    };

    let token = match env::var("GITLAB_TOKEN") {
        Ok(val) => val,
        Err(_)  => {
            panic!("Please set environment variable 'GITLAB_TOKEN'. Take it from http://{}/profile/account", hostname);
        },
    };

    let mut gl = GitLab::new_https("gitlab.com", &token);
    // for i in 1..82 {
    //     gl.set_pagination(Pagination{page: i, per_page: 1});
    //     println!("projects: {:?}", gl.projects().unwrap());
    // }
    gl.set_pagination(Pagination{page: 1, per_page: 100});
    let _projects = gl.projects().unwrap();
    // FIXME: Project's members are private
    // for project in projects {
    //     println!("{:?}", project.path_with_namespace);
    // }
}
<|endoftext|>


<commit_before>// Issue 61118 pointed out a case where we hit an ICE during code gen:
// the compiler assumed that `PartialEq` was always implemented on any
// use of a `const` item in a pattern context, but the pre-existing
// checking for the presence of `#[structural_match]` was too shallow
// (see rust-lang/rust#62307), and so we hit cases where we were
// trying to dispatch to `PartialEq` on types that did not implement
// that trait.

struct B(i32);

const A: &[B] = &[];

pub fn main() {
    match &[][..] {
        A => (),
        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
        _ => (),
    }
}
<commit_msg>fix typo in test.<commit_after>// Issue 61188 pointed out a case where we hit an ICE during code gen:
// the compiler assumed that `PartialEq` was always implemented on any
// use of a `const` item in a pattern context, but the pre-existing
// checking for the presence of `#[structural_match]` was too shallow
// (see rust-lang/rust#62307), and so we hit cases where we were
// trying to dispatch to `PartialEq` on types that did not implement
// that trait.

struct B(i32);

const A: &[B] = &[];

pub fn main() {
    match &[][..] {
        A => (),
        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
        _ => (),
    }
}
<|endoftext|>