<commit_before>use std::sync::Arc;

use wayland_backend::{
    protocol::ProtocolError,
    server::{ClientData, ClientId, DisconnectReason, InvalidId, ObjectData},
};

use crate::{dispatch::ResourceData, Dispatch, DisplayHandle, Resource};

/// A struct representing a Wayland client connected to your compositor.
#[derive(Clone, Debug)]
pub struct Client {
    pub(crate) id: ClientId,
    pub(crate) data: Arc<dyn ClientData>,
}

impl Client {
    pub(crate) fn from_id(handle: &DisplayHandle, id: ClientId) -> Result<Self, InvalidId> {
        let data = handle.handle.get_client_data(id.clone())?;
        Ok(Self { id, data })
    }

    /// The backend [`ClientId`] of this client
    pub fn id(&self) -> ClientId {
        self.id.clone()
    }

    /// Access the data associated to this client
    ///
    /// Returns [`None`] if the provided `Data` type parameter is not the correct one.
    pub fn get_data<Data: ClientData + 'static>(&self) -> Option<&Data> {
        (&*self.data).downcast_ref()
    }

    /// Access the pid/uid/gid of this client
    ///
    /// **Note:** You should be careful if you plan tu use this for security purposes, as it is possible for
    /// programs to spoof this kind of information.
    ///
    /// For a discussion about the subject of securely identifying clients, see
    /// <https://gitlab.freedesktop.org/wayland/weston/-/issues/206>
    pub fn get_credentials(
        &self,
        handle: &DisplayHandle,
    ) -> Result<crate::backend::Credentials, InvalidId> {
        handle.handle.get_client_credentials(self.id.clone())
    }

    /// Create a new Wayland object in the protocol state of this client
    ///
    /// The newly created resource should be immediately sent to the client through an associated event with
    /// a `new_id` argument. Not doing so risks corrupting the protocol state and causing protocol errors at
    /// a later time.
    pub fn create_resource<
        I: Resource + 'static,
        U: Send + Sync + 'static,
        D: Dispatch<I, U> + 'static,
    >(
        &self,
        handle: &DisplayHandle,
        version: u32,
        user_data: U,
    ) -> Result<I, InvalidId> {
        let id = handle.handle.create_object::<D>(
            self.id.clone(),
            I::interface(),
            version,
            Arc::new(ResourceData::<I, U>::new(user_data)) as Arc<_>,
        )?;
        I::from_id(handle, id)
    }

    /// Create a new Wayland object in the protocol state of this client, from an [`ObjectData`]
    ///
    /// This is a lower-level method than [`create_resource`](Client::create_resource), in case you need to
    /// bypass the [`Dispatch`] machinnery.
    ///
    /// The newly created resource should be immediately sent to the client through an associated event with
    /// a `new_id` argument. Not doing so risks corrupting the protocol state and causing protocol errors at
    /// a later time.
    pub fn create_resource_from_objdata<I: Resource + 'static, D: 'static>(
        &self,
        handle: &DisplayHandle,
        version: u32,
        obj_data: Arc<dyn ObjectData<D>>,
    ) -> Result<I, InvalidId> {
        let id =
            handle.handle.create_object::<D>(self.id.clone(), I::interface(), version, obj_data)?;
        I::from_id(handle, id)
    }

    /// Attempt to retrieve an object from this client's protocol state from its protocol id
    ///
    /// Will fail if either the provided protocol id does not correspond to any object, or if the
    /// corresponding object is not of the interface `I`.
    pub fn object_from_protocol_id<I: Resource + 'static>(
        &self,
        handle: &DisplayHandle,
        protocol_id: u32,
    ) -> Result<I, InvalidId> {
        let object_id =
            handle.handle.object_for_protocol_id(self.id.clone(), I::interface(), protocol_id)?;
        I::from_id(handle, object_id)
    }

    /// Kill this client by triggering a protocol error
    pub fn kill(&self, handle: &DisplayHandle, error: ProtocolError) {
        handle.handle.kill_client(self.id.clone(), DisconnectReason::ProtocolError(error))
    }
}

impl PartialEq for Client {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}
<commit_msg>server: fix clippy borrow lint<commit_after>use std::sync::Arc;

use wayland_backend::{
    protocol::ProtocolError,
    server::{ClientData, ClientId, DisconnectReason, InvalidId, ObjectData},
};

use crate::{dispatch::ResourceData, Dispatch, DisplayHandle, Resource};

/// A struct representing a Wayland client connected to your compositor.
#[derive(Clone, Debug)]
pub struct Client {
    pub(crate) id: ClientId,
    pub(crate) data: Arc<dyn ClientData>,
}

impl Client {
    pub(crate) fn from_id(handle: &DisplayHandle, id: ClientId) -> Result<Self, InvalidId> {
        let data = handle.handle.get_client_data(id.clone())?;
        Ok(Self { id, data })
    }

    /// The backend [`ClientId`] of this client
    pub fn id(&self) -> ClientId {
        self.id.clone()
    }

    /// Access the data associated to this client
    ///
    /// Returns [`None`] if the provided `Data` type parameter is not the correct one.
    pub fn get_data<Data: ClientData + 'static>(&self) -> Option<&Data> {
        (*self.data).downcast_ref()
    }

    /// Access the pid/uid/gid of this client
    ///
    /// **Note:** You should be careful if you plan tu use this for security purposes, as it is possible for
    /// programs to spoof this kind of information.
    ///
    /// For a discussion about the subject of securely identifying clients, see
    /// <https://gitlab.freedesktop.org/wayland/weston/-/issues/206>
    pub fn get_credentials(
        &self,
        handle: &DisplayHandle,
    ) -> Result<crate::backend::Credentials, InvalidId> {
        handle.handle.get_client_credentials(self.id.clone())
    }

    /// Create a new Wayland object in the protocol state of this client
    ///
    /// The newly created resource should be immediately sent to the client through an associated event with
    /// a `new_id` argument. Not doing so risks corrupting the protocol state and causing protocol errors at
    /// a later time.
    pub fn create_resource<
        I: Resource + 'static,
        U: Send + Sync + 'static,
        D: Dispatch<I, U> + 'static,
    >(
        &self,
        handle: &DisplayHandle,
        version: u32,
        user_data: U,
    ) -> Result<I, InvalidId> {
        let id = handle.handle.create_object::<D>(
            self.id.clone(),
            I::interface(),
            version,
            Arc::new(ResourceData::<I, U>::new(user_data)) as Arc<_>,
        )?;
        I::from_id(handle, id)
    }

    /// Create a new Wayland object in the protocol state of this client, from an [`ObjectData`]
    ///
    /// This is a lower-level method than [`create_resource`](Client::create_resource), in case you need to
    /// bypass the [`Dispatch`] machinnery.
    ///
    /// The newly created resource should be immediately sent to the client through an associated event with
    /// a `new_id` argument. Not doing so risks corrupting the protocol state and causing protocol errors at
    /// a later time.
    pub fn create_resource_from_objdata<I: Resource + 'static, D: 'static>(
        &self,
        handle: &DisplayHandle,
        version: u32,
        obj_data: Arc<dyn ObjectData<D>>,
    ) -> Result<I, InvalidId> {
        let id =
            handle.handle.create_object::<D>(self.id.clone(), I::interface(), version, obj_data)?;
        I::from_id(handle, id)
    }

    /// Attempt to retrieve an object from this client's protocol state from its protocol id
    ///
    /// Will fail if either the provided protocol id does not correspond to any object, or if the
    /// corresponding object is not of the interface `I`.
    pub fn object_from_protocol_id<I: Resource + 'static>(
        &self,
        handle: &DisplayHandle,
        protocol_id: u32,
    ) -> Result<I, InvalidId> {
        let object_id =
            handle.handle.object_for_protocol_id(self.id.clone(), I::interface(), protocol_id)?;
        I::from_id(handle, object_id)
    }

    /// Kill this client by triggering a protocol error
    pub fn kill(&self, handle: &DisplayHandle, error: ProtocolError) {
        handle.handle.kill_client(self.id.clone(), DisconnectReason::ProtocolError(error))
    }
}

impl PartialEq for Client {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}
<|endoftext|>


<commit_before>use self::streamql::statement;
pub use self::streamql::ParseError;
use super::row_builder::RowBuilder;
use super::schema::Type;

mod integration_tests;

peg_file! streamql("streamql.rustpeg");

pub fn parse_statement(query: &str) -> Result<Statement, ParseError> {
    statement(query)
}

#[derive(Debug)]
pub enum Statement {
    // Stream & Keys
    Insert(String, RowBuilder),
    // name
    DeclareStream(String, Vec<ColumnSpec>),
    DropStream,
    UseDatabase,
    // Stream
    Select(String),
    Subscribe,
}

enum Operator {
    Equal,
    NotEqual,
    GreaterThan,
    GreaterThanEqual,
    LessThan,
    LessThanEqual,
}

//struct Expression {
//    lhs:
//    operator: Operator,
//    rhs:
//}

#[derive(Debug)]
pub struct ColumnSpec {
    pub name: String,
    pub ftype: Type,
}

impl ColumnSpec {
    fn new(name: String, ftype: Type) -> ColumnSpec {
        ColumnSpec{name: name,
                   ftype: ftype}
    }
}

#[cfg(test)]
mod test {
    use super::parse_statement;
    use super::Statement;
    use super::streamql::*;
    use db::value::Value;

    #[test]
    fn test_basic_insert() {

        let result = parse_statement("INSERT INTO test set k=1;").unwrap();

        if let Statement::Insert(stream, builder) = result {
            assert_eq!(stream, String::from("test"));
        } else {
            panic!("")
        }
        let x = "INSERT INTO test set k=1, v=2;";
        let result = parse_statement(x).unwrap();

    }

    #[test]
    fn test_parsing_with_quoted_string() {
        let result = parse_statement("INSERT INTO test set k='test';").unwrap();
        let result = parse_statement("INSERT INTO test set k='test my ''friend''';").unwrap();

    }

    #[test]
    fn test_int_parsing() {
        let tmp = int_value("42").unwrap();
    }

    #[test]
    fn test_basic_string_parsing() {
        string("hello this is a test").unwrap();
    }

    #[test]
    fn test_escaped_string() {
        let x = string("hello this is a ''test''").unwrap();
        assert_eq!(x, "hello this is a 'test'");
    }

    #[test]
    fn test_quoted_string() {
        let x = "'it''s mine'";
        let p = quoted_string(x).unwrap();
        assert_eq!(p, "it's mine");
    }

    #[test]
    fn value_string_parsing() {
        let x = "'hello'";
        if Value::from(x) == value(x).unwrap() {
            assert_eq!(x, "hello");
        }

    }

    #[test]
    fn declare_stream_parsing() {
        let x = "declare stream readings ( ts int, val int, s text );";
        let p = parse_statement(x).unwrap();
    }

    #[test]
    fn test_basic_parse_column_specification() {
        let x = "ts int";
        let p = column_spec(x).unwrap();

        let x = "ts text";
        let p = column_spec(x).unwrap();
    }

    #[test]
    fn test_column_spec_list() {
        let x = "ts int, val int, s text ";
        let p = column_spec_list(x).unwrap();

        assert_eq!(p.len(), 3);

        assert_eq!(p[0].name, "ts");
        assert_eq!(p[1].name, "val");
        assert_eq!(p[2].name, "s");
    }

    #[test]
    fn test_select_queries() {
        let queries = ["select * from test",
                        "select name, age from users",
                        "select name from cities where state = 'CA'"];
        for q in queries.into_iter() {
            parse_statement(&q).expect(q);
        }

    }

    #[test]
    fn test_field_list() {
        let queries = ["name, email",
            "*", "stuff"];
        for q in queries.into_iter() {
            field_list(q).expect(q);
        }
    }

    #[test]
    fn test_where_clause() {
        let queries = ["where name = 'jon'",
        "where id = 5",
        "where name = 'bill' and age > 35"];
        for q in queries.into_iter() {
            field_list(q).expect(q);
        }

    }

}

<commit_msg>I think I've got this whole expression thing figured out with enum<commit_after>use self::streamql::statement;
pub use self::streamql::ParseError;
use super::row_builder::RowBuilder;
use super::schema::Type;
use super::value::Value;

mod integration_tests;

peg_file! streamql("streamql.rustpeg");

pub fn parse_statement(query: &str) -> Result<Statement, ParseError> {
    statement(query)
}

#[derive(Debug)]
pub enum Statement {
    // Stream & Keys
    Insert(String, RowBuilder),
    // name
    DeclareStream(String, Vec<ColumnSpec>),
    DropStream,
    UseDatabase,
    // Stream
    Select(String),
    Subscribe,
}

enum Operator {
    Equal,
    NotEqual,
    GreaterThan,
    GreaterThanEqual,
    LessThan,
    LessThanEqual,
}

enum Expression {
    Value(Value),
    Comparison(Operator, Box<Expression>, Box<Expression>),
    Function(String, Vec<Expression> )

}

#[derive(Debug)]
pub struct ColumnSpec {
    pub name: String,
    pub ftype: Type,
}

impl ColumnSpec {
    fn new(name: String, ftype: Type) -> ColumnSpec {
        ColumnSpec{name: name,
                   ftype: ftype}
    }
}

#[cfg(test)]
mod test {
    use super::parse_statement;
    use super::Statement;
    use super::streamql::*;
    use db::value::Value;

    #[test]
    fn test_basic_insert() {

        let result = parse_statement("INSERT INTO test set k=1;").unwrap();

        if let Statement::Insert(stream, builder) = result {
            assert_eq!(stream, String::from("test"));
        } else {
            panic!("")
        }
        let x = "INSERT INTO test set k=1, v=2;";
        let result = parse_statement(x).unwrap();

    }

    #[test]
    fn test_parsing_with_quoted_string() {
        let result = parse_statement("INSERT INTO test set k='test';").unwrap();
        let result = parse_statement("INSERT INTO test set k='test my ''friend''';").unwrap();

    }

    #[test]
    fn test_int_parsing() {
        let tmp = int_value("42").unwrap();
    }

    #[test]
    fn test_basic_string_parsing() {
        string("hello this is a test").unwrap();
    }

    #[test]
    fn test_escaped_string() {
        let x = string("hello this is a ''test''").unwrap();
        assert_eq!(x, "hello this is a 'test'");
    }

    #[test]
    fn test_quoted_string() {
        let x = "'it''s mine'";
        let p = quoted_string(x).unwrap();
        assert_eq!(p, "it's mine");
    }

    #[test]
    fn value_string_parsing() {
        let x = "'hello'";
        if Value::from(x) == value(x).unwrap() {
            assert_eq!(x, "hello");
        }

    }

    #[test]
    fn declare_stream_parsing() {
        let x = "declare stream readings ( ts int, val int, s text );";
        let p = parse_statement(x).unwrap();
    }

    #[test]
    fn test_basic_parse_column_specification() {
        let x = "ts int";
        let p = column_spec(x).unwrap();

        let x = "ts text";
        let p = column_spec(x).unwrap();
    }

    #[test]
    fn test_column_spec_list() {
        let x = "ts int, val int, s text ";
        let p = column_spec_list(x).unwrap();

        assert_eq!(p.len(), 3);

        assert_eq!(p[0].name, "ts");
        assert_eq!(p[1].name, "val");
        assert_eq!(p[2].name, "s");
    }

    #[test]
    fn test_select_queries() {
        let queries = ["select * from test",
                        "select name, age from users",
                        "select name from cities where state = 'CA'"];
        for q in queries.into_iter() {
            parse_statement(&q).expect(q);
        }

    }

    #[test]
    fn test_field_list() {
        let queries = ["name, email",
            "*", "stuff"];
        for q in queries.into_iter() {
            field_list(q).expect(q);
        }
    }

    #[test]
    fn test_where_clause() {
        let queries = ["where name = 'jon'",
        "where id = 5",
        "where name = 'bill' and age > 35"];
        for q in queries.into_iter() {
            field_list(q).expect(q);
        }

    }

}

<|endoftext|>


<commit_before>extern crate redis;

/// A DataStore needs to implement store and retrieve methods.
pub trait DataStore {
    fn store(&self, key: &str, value: &str) -> Result<(), DataStoreError>;
    fn retrieve(&self, key: &str) -> Result<String, DataStoreError>;
    fn delete(&self, key: &str) -> Result<(), DataStoreError>;
}

/// A struct representing a datastore error.
#[derive(Debug)]
pub struct DataStoreError {
    pub repr: ErrorKind,
}

/// An enum containing all possible error kinds.
#[derive(Debug)]
pub enum ErrorKind {
    RedisError(redis::RedisError),
}

impl From<redis::RedisError> for DataStoreError {
    fn from(err: redis::RedisError) -> DataStoreError {
        DataStoreError { repr: ErrorKind::RedisError(err) }
    }
}
<commit_msg>DataStore: Add Send trait<commit_after>extern crate redis;

/// A DataStore needs to implement store and retrieve methods.
pub trait DataStore : Send {
    fn store(&self, key: &str, value: &str) -> Result<(), DataStoreError>;
    fn retrieve(&self, key: &str) -> Result<String, DataStoreError>;
    fn delete(&self, key: &str) -> Result<(), DataStoreError>;
}

/// A struct representing a datastore error.
#[derive(Debug)]
pub struct DataStoreError {
    pub repr: ErrorKind,
}

/// An enum containing all possible error kinds.
#[derive(Debug)]
pub enum ErrorKind {
    RedisError(redis::RedisError),
}

impl From<redis::RedisError> for DataStoreError {
    fn from(err: redis::RedisError) -> DataStoreError {
        DataStoreError { repr: ErrorKind::RedisError(err) }
    }
}
<|endoftext|>


<commit_before><commit_msg>Adapt to new libimagstore::iter::Entries API<commit_after><|endoftext|>


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

extern crate gl;
extern crate libc;

use log;
use std;
use a = super::attrib;
use std::fmt;
use std::str;
use std::collections::HashSet;

mod rast;
mod shade;

pub type Buffer         = gl::types::GLuint;
pub type ArrayBuffer    = gl::types::GLuint;
pub type Shader         = gl::types::GLuint;
pub type Program        = gl::types::GLuint;
pub type FrameBuffer    = gl::types::GLuint;
pub type Surface        = gl::types::GLuint;
pub type Texture        = gl::types::GLuint;
pub type Sampler        = gl::types::GLuint;

fn get_uint(name: gl::types::GLenum) -> uint {
    let mut value = 0 as gl::types::GLint;
    unsafe { gl::GetIntegerv(name, &mut value) };
    value as uint
}

unsafe fn get_static_string(name: gl::types::GLenum) -> &'static str {
    let ptr = gl::GetString(name) as *const i8;
    debug_assert!(!ptr.is_null());
    str::raw::c_str_to_static_slice(ptr)
}

#[deriving(Eq, PartialEq, Ord, PartialOrd)]
pub struct Version(uint, uint, Option<uint>, &'static str);

impl Version {
    fn parse(src: &'static str) -> Result<Version, &'static str> {
        let (version, vendor_info) = src.find(' ').map_or((src, ""), |i| {
            (src.slice_to(i), src.slice_from(i + 1))
        });

        let mut it = version.split('.');
        let major = it.next().and_then(|x| from_str(x));
        let minor = it.next().and_then(|x| from_str(x));
        let revision = it.next().and_then(|x| from_str(x));
        let tail = it.next();

        match (major, minor, revision, tail) {
            (Some(major), Some(minor), revision, None) =>
                Ok(Version(major, minor, revision, vendor_info)),
            _ => Err(src),
        }
    }
}

impl fmt::Show for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Version(major, minor, Some(revision), "") =>
                write!(f, "Version({}.{}.{})", major, minor, revision),
            Version(major, minor, None, "") =>
                write!(f, "Version({}.{})", major, minor),
            Version(major, minor, Some(revision), vendor_info) =>
                write!(f, "Version({}.{}.{}, {})", major, minor, revision, vendor_info),
            Version(major, minor, None, vendor_info) =>
                write!(f, "Version({}.{}, {})", major, minor, vendor_info),
        }
    }
}

#[deriving(Show)]
pub struct Info {
    pub vendor: &'static str,
    pub renderer: &'static str,
    pub version: Version,
    pub shading_language: Version,
    pub extensions: HashSet<&'static str>,
}

impl Info {
    fn new() -> Info {
        let info = unsafe {
            let vendor = get_static_string(gl::VENDOR);
            let renderer = get_static_string(gl::RENDERER);
            let version = Version::parse(get_static_string(gl::VERSION)).unwrap();
            let shading_language = Version::parse(get_static_string(gl::SHADING_LANGUAGE_VERSION)).unwrap();
            let extensions = if version >= Version(3, 2, None, "") {
                let num_exts = get_uint(gl::NUM_EXTENSIONS) as gl::types::GLuint;
                range(0, num_exts).map(|i| {
                    str::raw::c_str_to_static_slice(
                        gl::GetStringi(gl::EXTENSIONS, i) as *const i8,
                    )
                }).collect()
            } else {
                // Fallback
                let bytes = gl::GetString(gl::EXTENSIONS);
                str::raw::c_str_to_static_slice(bytes as *const i8)
                    .split(' ').collect()
            };
            Info {
                vendor: vendor,
                renderer: renderer,
                version: version,
                shading_language: shading_language,
                extensions: extensions,
            }
        };
        info!("Vendor: {}", info.vendor);
        info!("Renderer: {}", info.renderer);
        info!("Version: {}", info.version);
        info!("Shading Language: {}", info.shading_language);
        info!("Loaded Extensions:")
        for extension in info.extensions.iter() {
            info!("- {}", *extension);
        }
        info
    }

    pub fn is_extension_supported(&self, s: &str) -> bool {
        self.extensions.contains_equiv(&s)
    }
}

pub struct GlBackEnd {
    caps: super::Capabilities,
    info: Info,
}

impl GlBackEnd {
    pub fn new(provider: &super::GlProvider) -> GlBackEnd {
        gl::load_with(|s| provider.get_proc_address(s));
        let info = Info::new();
        let caps = super::Capabilities {
            shader_model: shade::get_model(),
            max_draw_buffers: get_uint(gl::MAX_DRAW_BUFFERS),
            max_texture_size: get_uint(gl::MAX_TEXTURE_SIZE),
            max_vertex_attributes: get_uint(gl::MAX_VERTEX_ATTRIBS),
            uniform_block_supported: info.is_extension_supported("GL_ARB_uniform_buffer_object"),
            array_buffer_supported: info.is_extension_supported("GL_ARB_vertex_array_object"),
        };
        GlBackEnd {
            caps: caps,
            info: info,
        }
    }

    #[allow(dead_code)]
    fn check(&mut self) {
        debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
    }

    pub fn get_info<'a>(&'a self) -> &'a Info {
        &self.info
    }
}

impl super::ApiBackEnd for GlBackEnd {
    fn get_capabilities<'a>(&'a self) -> &'a super::Capabilities {
        &self.caps
    }

    fn create_buffer(&mut self) -> Buffer {
        let mut name = 0 as Buffer;
        unsafe{
            gl::GenBuffers(1, &mut name);
        }
        info!("\tCreated buffer {}", name);
        name
    }

    fn create_array_buffer(&mut self) -> Result<ArrayBuffer, ()> {
        if self.caps.array_buffer_supported {
            let mut name = 0 as ArrayBuffer;
            unsafe{
                gl::GenVertexArrays(1, &mut name);
            }
            info!("\tCreated array buffer {}", name);
            Ok(name)
        } else {
            error!("\tarray buffer creation unsupported, ignored")
            Err(())
        }
    }

    fn create_shader(&mut self, stage: super::shade::Stage, code: super::shade::ShaderSource) -> Result<Shader, super::shade::CreateShaderError> {
        let (name, info) = shade::create_shader(stage, code, self.get_capabilities().shader_model);
        info.map(|info| {
            let level = if name.is_err() { log::ERROR } else { log::WARN };
            log!(level, "\tShader compile log: {}", info);
        });
        name
    }

    fn create_program(&mut self, shaders: &[Shader]) -> Result<super::shade::ProgramMeta, ()> {
        let (meta, info) = shade::create_program(&self.caps, shaders);
        info.map(|info| {
            let level = if meta.is_err() { log::ERROR } else { log::WARN };
            log!(level, "\tProgram link log: {}", info);
        });
        meta
    }

    fn create_frame_buffer(&mut self) -> FrameBuffer {
        let mut name = 0 as FrameBuffer;
        unsafe{
            gl::GenFramebuffers(1, &mut name);
        }
        info!("\tCreated frame buffer {}", name);
        name
    }

    fn update_buffer<T>(&mut self, buffer: Buffer, data: &[T], usage: super::BufferUsage) {
        gl::BindBuffer(gl::ARRAY_BUFFER, buffer);
        let size = (data.len() * std::mem::size_of::<T>()) as gl::types::GLsizeiptr;
        let raw = data.as_ptr() as *const gl::types::GLvoid;
        let usage = match usage {
            super::UsageStatic  => gl::STATIC_DRAW,
            super::UsageDynamic => gl::DYNAMIC_DRAW,
            super::UsageStream  => gl::STREAM_DRAW,
        };
        unsafe{
            gl::BufferData(gl::ARRAY_BUFFER, size, raw, usage);
        }
    }

    fn process(&mut self, request: super::Request) {
        match request {
            super::CastClear(data) => {
                let mut flags = match data.color {
                    //gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
                    Some(super::target::Color([r,g,b,a])) => {
                        gl::ClearColor(r, g, b, a);
                        gl::COLOR_BUFFER_BIT
                    },
                    None => 0 as gl::types::GLenum
                };
                data.depth.map(|value| {
                    gl::DepthMask(gl::TRUE);
                    gl::ClearDepth(value as gl::types::GLclampd);
                    flags |= gl::DEPTH_BUFFER_BIT;
                });
                data.stencil.map(|value| {
                    gl::StencilMask(-1);
                    gl::ClearStencil(value as gl::types::GLint);
                    flags |= gl::STENCIL_BUFFER_BIT;
                });
                gl::Clear(flags);
            },
            super::CastBindProgram(program) => {
                gl::UseProgram(program);
            },
            super::CastBindArrayBuffer(array_buffer) => {
                if self.caps.array_buffer_supported {
                    gl::BindVertexArray(array_buffer);
                } else {
                    error!("Ignored unsupported GL Request: {}", request)
                }
            },
            super::CastBindAttribute(slot, buffer, count, el_type, stride, offset) => {
                let gl_type = match el_type {
                    a::Int(_, a::U8, a::Unsigned)  => gl::UNSIGNED_BYTE,
                    a::Int(_, a::U8, a::Signed)    => gl::BYTE,
                    a::Int(_, a::U16, a::Unsigned) => gl::UNSIGNED_SHORT,
                    a::Int(_, a::U16, a::Signed)   => gl::SHORT,
                    a::Int(_, a::U32, a::Unsigned) => gl::UNSIGNED_INT,
                    a::Int(_, a::U32, a::Signed)   => gl::INT,
                    a::Float(_, a::F16) => gl::HALF_FLOAT,
                    a::Float(_, a::F32) => gl::FLOAT,
                    a::Float(_, a::F64) => gl::DOUBLE,
                    _ => {
                        error!("Unsupported element type: {}", el_type);
                        return
                    }
                };
                gl::BindBuffer(gl::ARRAY_BUFFER, buffer);
                let offset = offset as *const gl::types::GLvoid;
                match el_type {
                    a::Int(a::IntRaw, _, _) => unsafe {
                        gl::VertexAttribIPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type,
                            stride as gl::types::GLint, offset);
                    },
                    a::Int(sub, _, _) => unsafe {
                        gl::VertexAttribPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type,
                            if sub == a::IntNormalized {gl::TRUE} else {gl::FALSE},
                            stride as gl::types::GLint, offset);
                    },
                    a::Float(a::FloatDefault, _) => unsafe {
                        gl::VertexAttribPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type, gl::FALSE,
                            stride as gl::types::GLint, offset);
                    },
                    a::Float(a::FloatPrecision, _) => unsafe {
                        gl::VertexAttribLPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type,
                            stride as gl::types::GLint, offset);
                    },
                    _ => ()
                }
                gl::EnableVertexAttribArray(slot as gl::types::GLuint);
            },
            super::CastBindIndex(buffer) => {
                gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, buffer);
            },
            super::CastBindFrameBuffer(frame_buffer) => {
                gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, frame_buffer);
            },
            super::CastBindTarget(target, plane) => {
                let attachment = match target {
                    super::target::TargetColor(index) =>
                        gl::COLOR_ATTACHMENT0 + (index as gl::types::GLenum),
                    super::target::TargetDepth => gl::DEPTH_ATTACHMENT,
                    super::target::TargetStencil => gl::STENCIL_ATTACHMENT,
                    super::target::TargetDepthStencil => gl::DEPTH_STENCIL_ATTACHMENT,
                };
                match plane {
                    super::target::PlaneEmpty => gl::FramebufferRenderbuffer
                        (gl::DRAW_FRAMEBUFFER, attachment, gl::RENDERBUFFER, 0),
                    super::target::PlaneSurface(name) => gl::FramebufferRenderbuffer
                        (gl::DRAW_FRAMEBUFFER, attachment, gl::RENDERBUFFER, name),
                    super::target::PlaneTexture(name, level) => gl::FramebufferTexture
                        (gl::DRAW_FRAMEBUFFER, attachment, name, level as gl::types::GLint),
                    super::target::PlaneTextureLayer(name, level, layer) => gl::FramebufferTextureLayer
                        (gl::DRAW_FRAMEBUFFER, attachment, name, level as gl::types::GLint, layer as gl::types::GLint),
                }
            },
            super::CastBindUniformBlock(program, index, loc, buffer) => {
                gl::UniformBlockBinding(program, index as gl::types::GLuint, loc as gl::types::GLuint);
                gl::BindBufferBase(gl::UNIFORM_BUFFER, loc as gl::types::GLuint, buffer);
            },
            super::CastBindUniform(loc, uniform) => {
                shade::bind_uniform(loc as gl::types::GLint, uniform);
            },
            super::CastPrimitiveState(prim) => {
                rast::bind_primitive(prim);
            },
            super::CastDepthStencilState(depth, stencil, cull) => {
                rast::bind_stencil(stencil, cull);
                rast::bind_depth(depth);
            },
            super::CastBlendState(blend) => {
                rast::bind_blend(blend);
            },
            super::CastUpdateBuffer(buffer, data) => {
                self.update_buffer(buffer, data.as_slice(), super::UsageDynamic);
            },
            super::CastDraw(start, count) => {
                gl::DrawArrays(gl::TRIANGLES,
                    start as gl::types::GLsizei,
                    count as gl::types::GLsizei);
                self.check();
            },
            super::CastDrawIndexed(start, count) => {
                let offset = start * (std::mem::size_of::<u16>() as u16);
                unsafe {
                    gl::DrawElements(gl::TRIANGLES,
                        count as gl::types::GLsizei,
                        gl::UNSIGNED_SHORT,
                        offset as *const gl::types::GLvoid);
                }
                self.check();
            },
            _ => fail!("Unknown GL request: {}", request)
        }
    }
}
<commit_msg>Fix capability detection on core profiles<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gl;
extern crate libc;

use log;
use std;
use a = super::attrib;
use std::fmt;
use std::str;
use std::collections::HashSet;

mod rast;
mod shade;

pub type Buffer         = gl::types::GLuint;
pub type ArrayBuffer    = gl::types::GLuint;
pub type Shader         = gl::types::GLuint;
pub type Program        = gl::types::GLuint;
pub type FrameBuffer    = gl::types::GLuint;
pub type Surface        = gl::types::GLuint;
pub type Texture        = gl::types::GLuint;
pub type Sampler        = gl::types::GLuint;

fn get_uint(name: gl::types::GLenum) -> uint {
    let mut value = 0 as gl::types::GLint;
    unsafe { gl::GetIntegerv(name, &mut value) };
    value as uint
}

unsafe fn get_static_string(name: gl::types::GLenum) -> &'static str {
    let ptr = gl::GetString(name) as *const i8;
    debug_assert!(!ptr.is_null());
    str::raw::c_str_to_static_slice(ptr)
}

#[deriving(Eq, PartialEq, Ord, PartialOrd)]
pub struct Version(uint, uint, Option<uint>, &'static str);

impl Version {
    fn parse(src: &'static str) -> Result<Version, &'static str> {
        let (version, vendor_info) = src.find(' ').map_or((src, ""), |i| {
            (src.slice_to(i), src.slice_from(i + 1))
        });

        let mut it = version.split('.');
        let major = it.next().and_then(|x| from_str(x));
        let minor = it.next().and_then(|x| from_str(x));
        let revision = it.next().and_then(|x| from_str(x));
        let tail = it.next();

        match (major, minor, revision, tail) {
            (Some(major), Some(minor), revision, None) =>
                Ok(Version(major, minor, revision, vendor_info)),
            _ => Err(src),
        }
    }
}

impl fmt::Show for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Version(major, minor, Some(revision), "") =>
                write!(f, "Version({}.{}.{})", major, minor, revision),
            Version(major, minor, None, "") =>
                write!(f, "Version({}.{})", major, minor),
            Version(major, minor, Some(revision), vendor_info) =>
                write!(f, "Version({}.{}.{}, {})", major, minor, revision, vendor_info),
            Version(major, minor, None, vendor_info) =>
                write!(f, "Version({}.{}, {})", major, minor, vendor_info),
        }
    }
}

#[deriving(Show)]
pub struct Info {
    pub vendor: &'static str,
    pub renderer: &'static str,
    pub version: Version,
    pub shading_language: Version,
    pub extensions: HashSet<&'static str>,
}

impl Info {
    fn new() -> Info {
        let info = unsafe {
            let vendor = get_static_string(gl::VENDOR);
            let renderer = get_static_string(gl::RENDERER);
            let version = Version::parse(get_static_string(gl::VERSION)).unwrap();
            let shading_language = Version::parse(get_static_string(gl::SHADING_LANGUAGE_VERSION)).unwrap();
            let extensions = if version >= Version(3, 2, None, "") {
                let num_exts = get_uint(gl::NUM_EXTENSIONS) as gl::types::GLuint;
                range(0, num_exts).map(|i| {
                    str::raw::c_str_to_static_slice(
                        gl::GetStringi(gl::EXTENSIONS, i) as *const i8,
                    )
                }).collect()
            } else {
                // Fallback
                let bytes = gl::GetString(gl::EXTENSIONS);
                str::raw::c_str_to_static_slice(bytes as *const i8)
                    .split(' ').collect()
            };
            Info {
                vendor: vendor,
                renderer: renderer,
                version: version,
                shading_language: shading_language,
                extensions: extensions,
            }
        };
        info!("Vendor: {}", info.vendor);
        info!("Renderer: {}", info.renderer);
        info!("Version: {}", info.version);
        info!("Shading Language: {}", info.shading_language);
        info!("Loaded Extensions:")
        for extension in info.extensions.iter() {
            info!("- {}", *extension);
        }
        info
    }

    pub fn is_extension_supported(&self, s: &str) -> bool {
        self.extensions.contains_equiv(&s)
    }
}

pub struct GlBackEnd {
    caps: super::Capabilities,
    info: Info,
}

impl GlBackEnd {
    pub fn new(provider: &super::GlProvider) -> GlBackEnd {
        gl::load_with(|s| provider.get_proc_address(s));
        let info = Info::new();
        let caps = super::Capabilities {
            shader_model: shade::get_model(),
            max_draw_buffers: get_uint(gl::MAX_DRAW_BUFFERS),
            max_texture_size: get_uint(gl::MAX_TEXTURE_SIZE),
            max_vertex_attributes: get_uint(gl::MAX_VERTEX_ATTRIBS),
            uniform_block_supported: info.version >= Version(3, 1, None, "")
                || info.is_extension_supported("GL_ARB_uniform_buffer_object"),
            array_buffer_supported: info.version >= Version(3, 0, None, "")
                || info.is_extension_supported("GL_ARB_vertex_array_object"),
        };
        GlBackEnd {
            caps: caps,
            info: info,
        }
    }

    #[allow(dead_code)]
    fn check(&mut self) {
        debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
    }

    pub fn get_info<'a>(&'a self) -> &'a Info {
        &self.info
    }
}

impl super::ApiBackEnd for GlBackEnd {
    fn get_capabilities<'a>(&'a self) -> &'a super::Capabilities {
        &self.caps
    }

    fn create_buffer(&mut self) -> Buffer {
        let mut name = 0 as Buffer;
        unsafe{
            gl::GenBuffers(1, &mut name);
        }
        info!("\tCreated buffer {}", name);
        name
    }

    fn create_array_buffer(&mut self) -> Result<ArrayBuffer, ()> {
        if self.caps.array_buffer_supported {
            let mut name = 0 as ArrayBuffer;
            unsafe{
                gl::GenVertexArrays(1, &mut name);
            }
            info!("\tCreated array buffer {}", name);
            Ok(name)
        } else {
            error!("\tarray buffer creation unsupported, ignored")
            Err(())
        }
    }

    fn create_shader(&mut self, stage: super::shade::Stage, code: super::shade::ShaderSource) -> Result<Shader, super::shade::CreateShaderError> {
        let (name, info) = shade::create_shader(stage, code, self.get_capabilities().shader_model);
        info.map(|info| {
            let level = if name.is_err() { log::ERROR } else { log::WARN };
            log!(level, "\tShader compile log: {}", info);
        });
        name
    }

    fn create_program(&mut self, shaders: &[Shader]) -> Result<super::shade::ProgramMeta, ()> {
        let (meta, info) = shade::create_program(&self.caps, shaders);
        info.map(|info| {
            let level = if meta.is_err() { log::ERROR } else { log::WARN };
            log!(level, "\tProgram link log: {}", info);
        });
        meta
    }

    fn create_frame_buffer(&mut self) -> FrameBuffer {
        let mut name = 0 as FrameBuffer;
        unsafe{
            gl::GenFramebuffers(1, &mut name);
        }
        info!("\tCreated frame buffer {}", name);
        name
    }

    fn update_buffer<T>(&mut self, buffer: Buffer, data: &[T], usage: super::BufferUsage) {
        gl::BindBuffer(gl::ARRAY_BUFFER, buffer);
        let size = (data.len() * std::mem::size_of::<T>()) as gl::types::GLsizeiptr;
        let raw = data.as_ptr() as *const gl::types::GLvoid;
        let usage = match usage {
            super::UsageStatic  => gl::STATIC_DRAW,
            super::UsageDynamic => gl::DYNAMIC_DRAW,
            super::UsageStream  => gl::STREAM_DRAW,
        };
        unsafe{
            gl::BufferData(gl::ARRAY_BUFFER, size, raw, usage);
        }
    }

    fn process(&mut self, request: super::Request) {
        match request {
            super::CastClear(data) => {
                let mut flags = match data.color {
                    //gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
                    Some(super::target::Color([r,g,b,a])) => {
                        gl::ClearColor(r, g, b, a);
                        gl::COLOR_BUFFER_BIT
                    },
                    None => 0 as gl::types::GLenum
                };
                data.depth.map(|value| {
                    gl::DepthMask(gl::TRUE);
                    gl::ClearDepth(value as gl::types::GLclampd);
                    flags |= gl::DEPTH_BUFFER_BIT;
                });
                data.stencil.map(|value| {
                    gl::StencilMask(-1);
                    gl::ClearStencil(value as gl::types::GLint);
                    flags |= gl::STENCIL_BUFFER_BIT;
                });
                gl::Clear(flags);
            },
            super::CastBindProgram(program) => {
                gl::UseProgram(program);
            },
            super::CastBindArrayBuffer(array_buffer) => {
                if self.caps.array_buffer_supported {
                    gl::BindVertexArray(array_buffer);
                } else {
                    error!("Ignored unsupported GL Request: {}", request)
                }
            },
            super::CastBindAttribute(slot, buffer, count, el_type, stride, offset) => {
                let gl_type = match el_type {
                    a::Int(_, a::U8, a::Unsigned)  => gl::UNSIGNED_BYTE,
                    a::Int(_, a::U8, a::Signed)    => gl::BYTE,
                    a::Int(_, a::U16, a::Unsigned) => gl::UNSIGNED_SHORT,
                    a::Int(_, a::U16, a::Signed)   => gl::SHORT,
                    a::Int(_, a::U32, a::Unsigned) => gl::UNSIGNED_INT,
                    a::Int(_, a::U32, a::Signed)   => gl::INT,
                    a::Float(_, a::F16) => gl::HALF_FLOAT,
                    a::Float(_, a::F32) => gl::FLOAT,
                    a::Float(_, a::F64) => gl::DOUBLE,
                    _ => {
                        error!("Unsupported element type: {}", el_type);
                        return
                    }
                };
                gl::BindBuffer(gl::ARRAY_BUFFER, buffer);
                let offset = offset as *const gl::types::GLvoid;
                match el_type {
                    a::Int(a::IntRaw, _, _) => unsafe {
                        gl::VertexAttribIPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type,
                            stride as gl::types::GLint, offset);
                    },
                    a::Int(sub, _, _) => unsafe {
                        gl::VertexAttribPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type,
                            if sub == a::IntNormalized {gl::TRUE} else {gl::FALSE},
                            stride as gl::types::GLint, offset);
                    },
                    a::Float(a::FloatDefault, _) => unsafe {
                        gl::VertexAttribPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type, gl::FALSE,
                            stride as gl::types::GLint, offset);
                    },
                    a::Float(a::FloatPrecision, _) => unsafe {
                        gl::VertexAttribLPointer(slot as gl::types::GLuint,
                            count as gl::types::GLint, gl_type,
                            stride as gl::types::GLint, offset);
                    },
                    _ => ()
                }
                gl::EnableVertexAttribArray(slot as gl::types::GLuint);
            },
            super::CastBindIndex(buffer) => {
                gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, buffer);
            },
            super::CastBindFrameBuffer(frame_buffer) => {
                gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, frame_buffer);
            },
            super::CastBindTarget(target, plane) => {
                let attachment = match target {
                    super::target::TargetColor(index) =>
                        gl::COLOR_ATTACHMENT0 + (index as gl::types::GLenum),
                    super::target::TargetDepth => gl::DEPTH_ATTACHMENT,
                    super::target::TargetStencil => gl::STENCIL_ATTACHMENT,
                    super::target::TargetDepthStencil => gl::DEPTH_STENCIL_ATTACHMENT,
                };
                match plane {
                    super::target::PlaneEmpty => gl::FramebufferRenderbuffer
                        (gl::DRAW_FRAMEBUFFER, attachment, gl::RENDERBUFFER, 0),
                    super::target::PlaneSurface(name) => gl::FramebufferRenderbuffer
                        (gl::DRAW_FRAMEBUFFER, attachment, gl::RENDERBUFFER, name),
                    super::target::PlaneTexture(name, level) => gl::FramebufferTexture
                        (gl::DRAW_FRAMEBUFFER, attachment, name, level as gl::types::GLint),
                    super::target::PlaneTextureLayer(name, level, layer) => gl::FramebufferTextureLayer
                        (gl::DRAW_FRAMEBUFFER, attachment, name, level as gl::types::GLint, layer as gl::types::GLint),
                }
            },
            super::CastBindUniformBlock(program, index, loc, buffer) => {
                gl::UniformBlockBinding(program, index as gl::types::GLuint, loc as gl::types::GLuint);
                gl::BindBufferBase(gl::UNIFORM_BUFFER, loc as gl::types::GLuint, buffer);
            },
            super::CastBindUniform(loc, uniform) => {
                shade::bind_uniform(loc as gl::types::GLint, uniform);
            },
            super::CastPrimitiveState(prim) => {
                rast::bind_primitive(prim);
            },
            super::CastDepthStencilState(depth, stencil, cull) => {
                rast::bind_stencil(stencil, cull);
                rast::bind_depth(depth);
            },
            super::CastBlendState(blend) => {
                rast::bind_blend(blend);
            },
            super::CastUpdateBuffer(buffer, data) => {
                self.update_buffer(buffer, data.as_slice(), super::UsageDynamic);
            },
            super::CastDraw(start, count) => {
                gl::DrawArrays(gl::TRIANGLES,
                    start as gl::types::GLsizei,
                    count as gl::types::GLsizei);
                self.check();
            },
            super::CastDrawIndexed(start, count) => {
                let offset = start * (std::mem::size_of::<u16>() as u16);
                unsafe {
                    gl::DrawElements(gl::TRIANGLES,
                        count as gl::types::GLsizei,
                        gl::UNSIGNED_SHORT,
                        offset as *const gl::types::GLvoid);
                }
                self.check();
            },
            _ => fail!("Unknown GL request: {}", request)
        }
    }
}
<|endoftext|>


<commit_before>extern crate util_kauk_rs;

use util_kauk_rs::cmd::native;
use std::env;

fn main() {
  let version: u8 = 5;  // Version that gets printed into the PBO filename

  let worlds = vec![
    "VR",
    "utes",
    "Sara",
    "SaraLite",
    "Sara_dbe1",
    "Chernarus",
    "Chernarus_Summer",
    "Porto",
    "IsolaDiCapraia",
    "Mountains_ACR",
    "Takistan",
    "Zargabad",
    "Woodland_ACR",
    "Bootcamp_ACR",
    "Desert_E",
    "ProvingGrounds_PMC",
    "Shapur_BAF",
    "fata",
    "Stratis",
    "anim_helvantis_v2",
    "Altis",
    "pja310"
  ];

  let cwd: String = get_cwd();

  for map in worlds {
    compile(cwd.as_ref(), version, map);
  }
}

fn get_cwd() -> String {
  let pathbuf = env::current_dir().unwrap();
  let path: &str = pathbuf.to_str().unwrap();
  format!("{}\\", path.to_string())
}

fn compile(path: &str,version: u8, map: &str) {
  let dirpath: String = format!("{}FP_ComfyDowntime.VR", path);
  let newpath: String = format!("{}FP_ComfyCompetition_{}.{}.pbo", path, version, map);
  native::run("PBOConsole", &["-pack", dirpath.as_ref(), newpath.as_ref()]);
}
<commit_msg>Fixed mission name<commit_after>extern crate util_kauk_rs;

use util_kauk_rs::cmd::native;
use std::env;

fn main() {
  let version: u8 = 5;  // Version that gets printed into the PBO filename

  let worlds = vec![
    "VR",
    "utes",
    "Sara",
    "SaraLite",
    "Sara_dbe1",
    "Chernarus",
    "Chernarus_Summer",
    "Porto",
    "IsolaDiCapraia",
    "Mountains_ACR",
    "Takistan",
    "Zargabad",
    "Woodland_ACR",
    "Bootcamp_ACR",
    "Desert_E",
    "ProvingGrounds_PMC",
    "Shapur_BAF",
    "fata",
    "Stratis",
    "anim_helvantis_v2",
    "Altis",
    "pja310"
  ];

  let cwd: String = get_cwd();

  for map in worlds {
    compile(cwd.as_ref(), version, map);
  }
}

fn get_cwd() -> String {
  let pathbuf = env::current_dir().unwrap();
  let path: &str = pathbuf.to_str().unwrap();
  format!("{}\\", path.to_string())
}

fn compile(path: &str,version: u8, map: &str) {
  let dirpath: String = format!("{}FP_ComfyDowntime.VR", path);
  let newpath: String = format!("{}FP_ComfyDowntime_{}.{}.pbo", path, version, map);
  native::run("PBOConsole", &["-pack", dirpath.as_ref(), newpath.as_ref()]);
}
<|endoftext|>


<commit_before>use std::iter;
use std::fmt;
use super::{QueueOfStrings, Queue};

const INITIAL_QUEUE_CAPACITY: usize = 2;

pub struct ResizingArrayQueueOfStrings {
    q: Vec<Option<String>>,
    head: usize,
    tail: usize
}

impl ResizingArrayQueueOfStrings {
    pub fn with_capacity(capacity: usize) -> ResizingArrayQueueOfStrings {
        let storage = iter::repeat(None).take(capacity).collect();

        ResizingArrayQueueOfStrings {
            q: storage,
            head: 0,
            tail: 0
        }
    }

    fn resize(&mut self, capacity: usize) {
        let cap = self.q.len();
        let mut new_storage: Vec<Option<String>> = iter::repeat(None).take(capacity).collect();
        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        for i in self.head .. tail{
            new_storage[i] = self.q[i % cap].take();
        }
        self.q = new_storage;
        // self.head = self.head
        self.tail = tail
    }
}

impl QueueOfStrings for ResizingArrayQueueOfStrings {
    fn new() -> ResizingArrayQueueOfStrings {
        let storage = iter::repeat(None).take(INITIAL_QUEUE_CAPACITY).collect();

        ResizingArrayQueueOfStrings {
            q: storage,
            head: 0,
            tail: 0
        }
    }

    fn is_empty(&self) -> bool {
        self.head == self.tail
    }

    fn enqueue(&mut self, item: String) {
        let mut cap = self.q.len();
        self.q[self.tail % cap] = Some(item);
        self.tail = (self.tail + 1) % cap;
        if self.q[self.tail % cap].is_some() {
            cap = 2 * cap;
            self.resize(cap);
        }
    }

    fn dequeue(&mut self) -> String {
        let cap = self.q.len();
        let item = self.q[self.head % cap].take();
        self.head = (self.head + 1) % cap;
        item.unwrap()
    }

    fn size(&self) -> usize {
        let cap = self.q.len();
        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        tail - self.head
    }
}

// generic ResizingArrayQueue
pub struct ResizingArrayQueue<T> {
    q: Vec<Option<T>>,
    head: usize,
    tail: usize
}

impl<T> ResizingArrayQueue<T> {
    pub fn with_capacity(capacity: usize) -> ResizingArrayQueue<T> {
        let mut storage = Vec::with_capacity(capacity);
        for _ in 0 .. capacity {
            storage.push(None);
        }

        ResizingArrayQueue {
            q: storage,
            head: 0,
            tail: 0
        }
    }

    fn resize(&mut self, capacity: usize) {
        let cap = self.q.len();
        let mut new_storage: Vec<Option<T>> = Vec::with_capacity(capacity);

        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        for i in 0 .. capacity {
            if i >= self.head && i < tail {
                new_storage.push(self.q[i % cap].take());
            } else {
                new_storage.push(None);
            }

        }
        self.q = new_storage;
        self.tail = tail
    }
}

impl<T> Queue<T> for ResizingArrayQueue<T> {
    fn new() -> ResizingArrayQueue<T> {
        ResizingArrayQueue::with_capacity(INITIAL_QUEUE_CAPACITY)
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.head == self.tail
    }

    fn enqueue(&mut self, item: T) {
        let mut cap = self.q.len();
        self.q[self.tail % cap] = Some(item);
        self.tail = (self.tail + 1) % cap;
        // if resize before enqueue, is_empty() will fail.
        if self.q[self.tail % cap].is_some() {
            cap = 2 * cap;
            self.resize(cap);
        }
    }

    fn dequeue(&mut self) -> Option<T> {
        if self.is_empty() {
            return None;
        }
        let cap = self.q.len();
        let item = self.q[self.head % cap].take();
        self.head = (self.head + 1) % cap;
        item
    }

    fn size(&self) -> usize {
        let cap = self.q.len();
        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        tail - self.head
    }
}

impl<T: fmt::Debug> fmt::Debug for ResizingArrayQueue<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.head < self.tail {
            for item in self.q[self.head .. self.tail].iter() {
                try!(write!(f, "{:?}, ", item.as_ref().unwrap()));
            }
        } else {
            for item in self.q[self.head ..].iter() {
                try!(write!(f, "{:?}, ", item));
            }
            for item in self.q[.. self.tail].iter() {
                try!(write!(f, "{:?}, ", item));
            }
        }
        Ok(())
    }
}

#[test]
fn test_resizing_array_queue_of_strings() {
    let mut queue: ResizingArrayQueueOfStrings = QueueOfStrings::new();

    assert!(queue.is_empty());
    let mut result = "to be or not to be".split(' ');

    for s in "to be or not to - be - - that - - - is".split(' ') {
        if s == "-" {
            assert_eq!(&queue.dequeue(), result.next().unwrap())
        } else {
            queue.enqueue(s.into())
        }
    }
    assert!(!queue.is_empty());
    assert_eq!(2, queue.size());
}

#[test]
fn test_resizing_array_queue() {
    let mut queue: ResizingArrayQueue<String> = Queue::new();

    assert!(queue.is_empty());
    let mut result = "to be or not to be".split(' ');

    for s in "to be or not to - be - - that - - - is".split(' ') {
        if s == "-" {
            assert_eq!(queue.dequeue(), result.next().map(|s| s.into()))
        } else {
            queue.enqueue(s.into())
        }
    }
    assert!(!queue.is_empty());
    assert_eq!(2, queue.size());
}
<commit_msg>stacks_and_queues/resizing_array_queue: impl IntoIterator for ResizingArrayQueue<commit_after>use std::iter;
use std::fmt;
use super::{QueueOfStrings, Queue};

const INITIAL_QUEUE_CAPACITY: usize = 2;

pub struct ResizingArrayQueueOfStrings {
    q: Vec<Option<String>>,
    head: usize,
    tail: usize
}

impl ResizingArrayQueueOfStrings {
    pub fn with_capacity(capacity: usize) -> ResizingArrayQueueOfStrings {
        let storage = iter::repeat(None).take(capacity).collect();

        ResizingArrayQueueOfStrings {
            q: storage,
            head: 0,
            tail: 0
        }
    }

    fn resize(&mut self, capacity: usize) {
        let cap = self.q.len();
        let mut new_storage: Vec<Option<String>> = iter::repeat(None).take(capacity).collect();
        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        for i in self.head .. tail{
            new_storage[i] = self.q[i % cap].take();
        }
        self.q = new_storage;
        // self.head = self.head
        self.tail = tail
    }
}

impl QueueOfStrings for ResizingArrayQueueOfStrings {
    fn new() -> ResizingArrayQueueOfStrings {
        let storage = iter::repeat(None).take(INITIAL_QUEUE_CAPACITY).collect();

        ResizingArrayQueueOfStrings {
            q: storage,
            head: 0,
            tail: 0
        }
    }

    fn is_empty(&self) -> bool {
        self.head == self.tail
    }

    fn enqueue(&mut self, item: String) {
        let mut cap = self.q.len();
        self.q[self.tail % cap] = Some(item);
        self.tail = (self.tail + 1) % cap;
        if self.q[self.tail % cap].is_some() {
            cap = 2 * cap;
            self.resize(cap);
        }
    }

    fn dequeue(&mut self) -> String {
        let cap = self.q.len();
        let item = self.q[self.head % cap].take();
        self.head = (self.head + 1) % cap;
        item.unwrap()
    }

    fn size(&self) -> usize {
        let cap = self.q.len();
        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        tail - self.head
    }
}

// generic ResizingArrayQueue
pub struct ResizingArrayQueue<T> {
    q: Vec<Option<T>>,
    head: usize,
    tail: usize
}

impl<T> ResizingArrayQueue<T> {
    pub fn with_capacity(capacity: usize) -> ResizingArrayQueue<T> {
        let mut storage = Vec::with_capacity(capacity);
        for _ in 0 .. capacity {
            storage.push(None);
        }

        ResizingArrayQueue {
            q: storage,
            head: 0,
            tail: 0
        }
    }

    fn resize(&mut self, capacity: usize) {
        let cap = self.q.len();
        let mut new_storage: Vec<Option<T>> = Vec::with_capacity(capacity);

        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        for i in 0 .. capacity {
            if i >= self.head && i < tail {
                new_storage.push(self.q[i % cap].take());
            } else {
                new_storage.push(None);
            }

        }
        self.q = new_storage;
        self.tail = tail
    }
}

impl<T> Queue<T> for ResizingArrayQueue<T> {
    fn new() -> ResizingArrayQueue<T> {
        ResizingArrayQueue::with_capacity(INITIAL_QUEUE_CAPACITY)
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.head == self.tail
    }

    fn enqueue(&mut self, item: T) {
        let mut cap = self.q.len();
        self.q[self.tail % cap] = Some(item);
        self.tail = (self.tail + 1) % cap;
        // if resize before enqueue, is_empty() will fail.
        if self.q[self.tail % cap].is_some() {
            cap = 2 * cap;
            self.resize(cap);
        }
    }

    fn dequeue(&mut self) -> Option<T> {
        if self.is_empty() {
            return None;
        }
        let cap = self.q.len();
        let item = self.q[self.head % cap].take();
        self.head = (self.head + 1) % cap;
        item
    }

    fn size(&self) -> usize {
        let cap = self.q.len();
        let tail = if self.tail > self.head {
            self.tail
        } else {
            self.tail + cap
        };
        tail - self.head
    }
}

impl<T: fmt::Debug> fmt::Debug for ResizingArrayQueue<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.head < self.tail {
            for item in self.q[self.head .. self.tail].iter() {
                try!(write!(f, "{:?}, ", item.as_ref().unwrap()));
            }
        } else {
            for item in self.q[self.head ..].iter() {
                try!(write!(f, "{:?}, ", item));
            }
            for item in self.q[.. self.tail].iter() {
                try!(write!(f, "{:?}, ", item));
            }
        }
        Ok(())
    }
}

pub struct IntoIter<T> {
    queue: ResizingArrayQueue<T>
}

impl<T> Iterator for IntoIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        self.queue.dequeue()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.size(), Some(self.size()))
    }
}

impl<T> IntoIterator for ResizingArrayQueue<T> {
    type Item = T;
    type IntoIter = IntoIter<T>;

    fn into_iter(self) -> IntoIter<T> {
        IntoIter { queue: self }
    }
}

#[test]
fn test_resizing_array_queue_of_strings() {
    let mut queue: ResizingArrayQueueOfStrings = QueueOfStrings::new();

    assert!(queue.is_empty());
    let mut result = "to be or not to be".split(' ');

    for s in "to be or not to - be - - that - - - is".split(' ') {
        if s == "-" {
            assert_eq!(&queue.dequeue(), result.next().unwrap())
        } else {
            queue.enqueue(s.into())
        }
    }
    assert!(!queue.is_empty());
    assert_eq!(2, queue.size());
}

#[test]
fn test_resizing_array_queue() {
    let mut queue: ResizingArrayQueue<String> = Queue::new();

    assert!(queue.is_empty());
    let mut result = "to be or not to be".split(' ');

    for s in "to be or not to - be - - that - - - is".split(' ') {
        if s == "-" {
            assert_eq!(queue.dequeue(), result.next().map(|s| s.into()))
        } else {
            queue.enqueue(s.into())
        }
    }
    assert!(!queue.is_empty());
    assert_eq!(2, queue.size());
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::collections::HashSet;

use ursa::cl::{
    CredentialKeyCorrectnessProof,
    CredentialPrivateKey,
    CredentialPublicKey,
    CredentialSignature,
    Nonce,
    RevocationKeyPrivate,
    RevocationRegistry,
    RevocationRegistryDelta,
    RevocationTailsAccessor,
    RevocationTailsGenerator,
    SignatureCorrectnessProof,
};
use ursa::cl::issuer::Issuer as CryptoIssuer;

use domain::anoncreds::credential::AttributeValues;
use domain::anoncreds::credential_definition::{CredentialDefinitionData, CredentialDefinitionV1 as CredentialDefinition};
use domain::anoncreds::credential_request::CredentialRequest;
use domain::anoncreds::revocation_registry_definition::{RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValuePublicKeys};
use errors::prelude::*;
use services::anoncreds::helpers::*;

pub struct Issuer {}

impl Issuer {
    pub fn new() -> Issuer {
        Issuer {}
    }

    pub fn new_credential_definition(attr_names: &HashSet<String>,
                                     support_revocation: bool) -> IndyResult<(CredentialDefinitionData,
                                                                              CredentialPrivateKey,
                                                                              CredentialKeyCorrectnessProof)> {
        trace!("new_credential_definition >>> attr_names: {:?}, support_revocation: {:?}", attr_names, support_revocation);

        let credential_schema = build_credential_schema(attr_names)?;
        let non_credential_schema = build_non_credential_schema()?;

        let (credential_public_key, credential_private_key, credential_key_correctness_proof) =
            CryptoIssuer::new_credential_def(&credential_schema, &non_credential_schema, support_revocation)?;

        let credential_definition_value = CredentialDefinitionData {
            primary: credential_public_key.get_primary_key()?.try_clone()?,
            revocation: credential_public_key.get_revocation_key()?.clone(),
        };

        trace!("new_credential_definition <<< credential_definition_value: {:?}, credential_private_key: {:?}, credential_key_correctness_proof: {:?}",
               credential_definition_value, secret!(&credential_private_key), credential_key_correctness_proof);

        Ok((credential_definition_value, credential_private_key, credential_key_correctness_proof))
    }

    pub fn new_revocation_registry(&self,
                                   cred_def: &CredentialDefinition,
                                   max_cred_num: u32,
                                   issuance_by_default: bool,
                                   issuer_did: &str) -> IndyResult<(RevocationRegistryDefinitionValuePublicKeys,
                                                                    RevocationKeyPrivate,
                                                                    RevocationRegistry,
                                                                    RevocationTailsGenerator)> {
        trace!("new_revocation_registry >>> pub_key: {:?}, max_cred_num: {:?}, issuance_by_default: {:?}, issuer_did: {:?}",
               cred_def, max_cred_num, issuance_by_default, issuer_did);

        let credential_pub_key =
            CredentialPublicKey::build_from_parts(&cred_def.value.primary, cred_def.value.revocation.as_ref())?;

        let (rev_key_pub, rev_key_priv, rev_reg_entry, rev_tails_generator) =
            CryptoIssuer::new_revocation_registry_def(&credential_pub_key, max_cred_num, issuance_by_default)?;

        let rev_keys_pub = RevocationRegistryDefinitionValuePublicKeys {
            accum_key: rev_key_pub
        };

        trace!("new_revocation_registry <<< rev_keys_pub: {:?}, rev_key_priv: {:?}, rev_reg_entry: {:?}, rev_tails_generator: {:?}",
               rev_keys_pub, secret!(&rev_key_priv), rev_reg_entry, rev_tails_generator);

        Ok((rev_keys_pub, rev_key_priv, rev_reg_entry, rev_tails_generator))
    }

    pub fn new_credential<RTA>(&self,
                               cred_def: &CredentialDefinition,
                               cred_priv_key: &CredentialPrivateKey,
                               cred_issuance_blinding_nonce: &Nonce,
                               cred_request: &CredentialRequest,
                               cred_values: &HashMap<String, AttributeValues>,
                               rev_idx: Option<u32>,
                               rev_reg_def: Option<&RevocationRegistryDefinitionV1>,
                               rev_reg: Option<&mut RevocationRegistry>,
                               rev_key_priv: Option<&RevocationKeyPrivate>,
                               rev_tails_accessor: Option<&RTA>) -> IndyResult<(CredentialSignature,
                                                                                SignatureCorrectnessProof,
                                                                                Option<RevocationRegistryDelta>)> where RTA: RevocationTailsAccessor {
        trace!("new_credential >>> cred_def: {:?}, cred_priv_key: {:?}, cred_issuance_blinding_nonce: {:?}, cred_request: {:?},\
               cred_values: {:?}, rev_idx: {:?}, rev_reg_def: {:?}, rev_reg: {:?}, rev_key_priv: {:?}",
               cred_def, secret!(&cred_priv_key), secret!(&cred_issuance_blinding_nonce), secret!(&cred_request), secret!(&cred_values), secret!(&rev_idx),
               rev_reg_def, rev_reg, secret!(&rev_key_priv));

        let credential_values = build_credential_values(&cred_values, None)?;
        let credential_pub_key = CredentialPublicKey::build_from_parts(&cred_def.value.primary, cred_def.value.revocation.as_ref())?;

        let (credential_signature, signature_correctness_proof, rev_reg_delta) =
            if rev_idx.is_some() {
                let rev_idx = rev_idx.unwrap();

                let rev_reg = rev_reg
                    .ok_or_else(||err_msg(IndyErrorKind::InvalidState, "RevocationRegistry not found"))?;

                let rev_key_priv = rev_key_priv
                    .ok_or_else(||err_msg(IndyErrorKind::InvalidState, "RevocationKeyPrivate not found"))?;

                let rev_reg_def = rev_reg_def
                    .ok_or_else(||err_msg(IndyErrorKind::InvalidState, "RevocationRegistryDefinitionValue not found"))?;

                let rev_tails_accessor = rev_tails_accessor
                    .ok_or_else(||err_msg(IndyErrorKind::InvalidState, "RevocationTailsAccessor not found"))?;

                CryptoIssuer::sign_credential_with_revoc(&cred_request.prover_did,
                                                         &cred_request.blinded_ms,
                                                         &cred_request.blinded_ms_correctness_proof,
                                                         cred_issuance_blinding_nonce,
                                                         &cred_request.nonce,
                                                         &credential_values,
                                                         &credential_pub_key,
                                                         &cred_priv_key,
                                                         rev_idx,
                                                         rev_reg_def.value.max_cred_num,
                                                         rev_reg_def.value.issuance_type.to_bool(),
                                                         rev_reg,
                                                         rev_key_priv,
                                                         rev_tails_accessor)?
            } else {
                let (signature, correctness_proof) =
                    CryptoIssuer::sign_credential(&cred_request.prover_did,
                                                  &cred_request.blinded_ms,
                                                  &cred_request.blinded_ms_correctness_proof,
                                                  cred_issuance_blinding_nonce,
                                                  &cred_request.nonce,
                                                  &credential_values,
                                                  &credential_pub_key,
                                                  &cred_priv_key)?;
                (signature, correctness_proof, None)
            };

        trace!("new_credential <<< credential_signature {:?}, signature_correctness_proof {:?}, rev_reg_delta {:?}",
               secret!(&credential_signature), secret!(&signature_correctness_proof), rev_reg_delta);

        Ok((credential_signature, signature_correctness_proof, rev_reg_delta))
    }

    pub fn revoke<RTA>(&self,
                       rev_reg: &mut RevocationRegistry,
                       max_cred_num: u32,
                       rev_idx: u32,
                       rev_tails_accessor: &RTA) -> IndyResult<RevocationRegistryDelta> where RTA: RevocationTailsAccessor {
        trace!("revoke >>> rev_reg: {:?}, max_cred_num: {:?}, rev_idx: {:?}", rev_reg, max_cred_num, secret!(&rev_idx));

        let rev_reg_delta = CryptoIssuer::revoke_credential(rev_reg, max_cred_num, rev_idx, rev_tails_accessor)?;

        trace!("recovery <<< rev_reg_delta {:?}", rev_reg_delta);

        Ok(rev_reg_delta)
    }

    #[allow(dead_code)]
    pub fn recovery<RTA>(&self,
                         rev_reg: &mut RevocationRegistry,
                         max_cred_num: u32,
                         rev_idx: u32,
                         rev_tails_accessor: &RTA) -> IndyResult<RevocationRegistryDelta> where RTA: RevocationTailsAccessor {
        trace!("revoke >>> rev_reg: {:?}, max_cred_num: {:?}, rev_idx: {:?}", rev_reg, max_cred_num, secret!(&rev_idx));

        let rev_reg_delta = CryptoIssuer::recovery_credential(rev_reg, max_cred_num, rev_idx, rev_tails_accessor)?;

        trace!("recovery <<< rev_reg_delta {:?}", rev_reg_delta);

        Ok(rev_reg_delta)
    }
}
<commit_msg>remove unwrap<commit_after>use std::collections::HashMap;
use std::collections::HashSet;

use ursa::cl::{
    CredentialKeyCorrectnessProof,
    CredentialPrivateKey,
    CredentialPublicKey,
    CredentialSignature,
    Nonce,
    RevocationKeyPrivate,
    RevocationRegistry,
    RevocationRegistryDelta,
    RevocationTailsAccessor,
    RevocationTailsGenerator,
    SignatureCorrectnessProof,
};
use ursa::cl::issuer::Issuer as CryptoIssuer;

use domain::anoncreds::credential::AttributeValues;
use domain::anoncreds::credential_definition::{CredentialDefinitionData, CredentialDefinitionV1 as CredentialDefinition};
use domain::anoncreds::credential_request::CredentialRequest;
use domain::anoncreds::revocation_registry_definition::{RevocationRegistryDefinitionV1, RevocationRegistryDefinitionValuePublicKeys};
use errors::prelude::*;
use services::anoncreds::helpers::*;

pub struct Issuer {}

impl Issuer {
    pub fn new() -> Issuer {
        Issuer {}
    }

    pub fn new_credential_definition(attr_names: &HashSet<String>,
                                     support_revocation: bool) -> IndyResult<(CredentialDefinitionData,
                                                                              CredentialPrivateKey,
                                                                              CredentialKeyCorrectnessProof)> {
        trace!("new_credential_definition >>> attr_names: {:?}, support_revocation: {:?}", attr_names, support_revocation);

        let credential_schema = build_credential_schema(attr_names)?;
        let non_credential_schema = build_non_credential_schema()?;

        let (credential_public_key, credential_private_key, credential_key_correctness_proof) =
            CryptoIssuer::new_credential_def(&credential_schema, &non_credential_schema, support_revocation)?;

        let credential_definition_value = CredentialDefinitionData {
            primary: credential_public_key.get_primary_key()?.try_clone()?,
            revocation: credential_public_key.get_revocation_key()?.clone(),
        };

        trace!("new_credential_definition <<< credential_definition_value: {:?}, credential_private_key: {:?}, credential_key_correctness_proof: {:?}",
               credential_definition_value, secret!(&credential_private_key), credential_key_correctness_proof);

        Ok((credential_definition_value, credential_private_key, credential_key_correctness_proof))
    }

    pub fn new_revocation_registry(&self,
                                   cred_def: &CredentialDefinition,
                                   max_cred_num: u32,
                                   issuance_by_default: bool,
                                   issuer_did: &str) -> IndyResult<(RevocationRegistryDefinitionValuePublicKeys,
                                                                    RevocationKeyPrivate,
                                                                    RevocationRegistry,
                                                                    RevocationTailsGenerator)> {
        trace!("new_revocation_registry >>> pub_key: {:?}, max_cred_num: {:?}, issuance_by_default: {:?}, issuer_did: {:?}",
               cred_def, max_cred_num, issuance_by_default, issuer_did);

        let credential_pub_key =
            CredentialPublicKey::build_from_parts(&cred_def.value.primary, cred_def.value.revocation.as_ref())?;

        let (rev_key_pub, rev_key_priv, rev_reg_entry, rev_tails_generator) =
            CryptoIssuer::new_revocation_registry_def(&credential_pub_key, max_cred_num, issuance_by_default)?;

        let rev_keys_pub = RevocationRegistryDefinitionValuePublicKeys {
            accum_key: rev_key_pub
        };

        trace!("new_revocation_registry <<< rev_keys_pub: {:?}, rev_key_priv: {:?}, rev_reg_entry: {:?}, rev_tails_generator: {:?}",
               rev_keys_pub, secret!(&rev_key_priv), rev_reg_entry, rev_tails_generator);

        Ok((rev_keys_pub, rev_key_priv, rev_reg_entry, rev_tails_generator))
    }

    pub fn new_credential<RTA>(&self,
                               cred_def: &CredentialDefinition,
                               cred_priv_key: &CredentialPrivateKey,
                               cred_issuance_blinding_nonce: &Nonce,
                               cred_request: &CredentialRequest,
                               cred_values: &HashMap<String, AttributeValues>,
                               rev_idx: Option<u32>,
                               rev_reg_def: Option<&RevocationRegistryDefinitionV1>,
                               rev_reg: Option<&mut RevocationRegistry>,
                               rev_key_priv: Option<&RevocationKeyPrivate>,
                               rev_tails_accessor: Option<&RTA>) -> IndyResult<(CredentialSignature,
                                                                                SignatureCorrectnessProof,
                                                                                Option<RevocationRegistryDelta>)> where RTA: RevocationTailsAccessor {
        trace!("new_credential >>> cred_def: {:?}, cred_priv_key: {:?}, cred_issuance_blinding_nonce: {:?}, cred_request: {:?},\
               cred_values: {:?}, rev_idx: {:?}, rev_reg_def: {:?}, rev_reg: {:?}, rev_key_priv: {:?}",
               cred_def, secret!(&cred_priv_key), secret!(&cred_issuance_blinding_nonce), secret!(&cred_request), secret!(&cred_values), secret!(&rev_idx),
               rev_reg_def, rev_reg, secret!(&rev_key_priv));

        let credential_values = build_credential_values(&cred_values, None)?;
        let credential_pub_key = CredentialPublicKey::build_from_parts(&cred_def.value.primary, cred_def.value.revocation.as_ref())?;

        let (credential_signature, signature_correctness_proof, rev_reg_delta) =
            match rev_idx {
                Some(rev_idx) => {
                    let rev_reg = rev_reg
                        .ok_or_else(|| err_msg(IndyErrorKind::InvalidState, "RevocationRegistry not found"))?;

                    let rev_key_priv = rev_key_priv
                        .ok_or_else(|| err_msg(IndyErrorKind::InvalidState, "RevocationKeyPrivate not found"))?;

                    let rev_reg_def = rev_reg_def
                        .ok_or_else(|| err_msg(IndyErrorKind::InvalidState, "RevocationRegistryDefinitionValue not found"))?;

                    let rev_tails_accessor = rev_tails_accessor
                        .ok_or_else(|| err_msg(IndyErrorKind::InvalidState, "RevocationTailsAccessor not found"))?;

                    CryptoIssuer::sign_credential_with_revoc(&cred_request.prover_did,
                                                             &cred_request.blinded_ms,
                                                             &cred_request.blinded_ms_correctness_proof,
                                                             cred_issuance_blinding_nonce,
                                                             &cred_request.nonce,
                                                             &credential_values,
                                                             &credential_pub_key,
                                                             &cred_priv_key,
                                                             rev_idx,
                                                             rev_reg_def.value.max_cred_num,
                                                             rev_reg_def.value.issuance_type.to_bool(),
                                                             rev_reg,
                                                             rev_key_priv,
                                                             rev_tails_accessor)?
                },
                None => {
                    let (signature, correctness_proof) =
                        CryptoIssuer::sign_credential(&cred_request.prover_did,
                                                      &cred_request.blinded_ms,
                                                      &cred_request.blinded_ms_correctness_proof,
                                                      cred_issuance_blinding_nonce,
                                                      &cred_request.nonce,
                                                      &credential_values,
                                                      &credential_pub_key,
                                                      &cred_priv_key)?;
                    (signature, correctness_proof, None)
                }
            };

        trace!("new_credential <<< credential_signature {:?}, signature_correctness_proof {:?}, rev_reg_delta {:?}",
               secret!(&credential_signature), secret!(&signature_correctness_proof), rev_reg_delta);

        Ok((credential_signature, signature_correctness_proof, rev_reg_delta))
    }

    pub fn revoke<RTA>(&self,
                       rev_reg: &mut RevocationRegistry,
                       max_cred_num: u32,
                       rev_idx: u32,
                       rev_tails_accessor: &RTA) -> IndyResult<RevocationRegistryDelta> where RTA: RevocationTailsAccessor {
        trace!("revoke >>> rev_reg: {:?}, max_cred_num: {:?}, rev_idx: {:?}", rev_reg, max_cred_num, secret!(&rev_idx));

        let rev_reg_delta = CryptoIssuer::revoke_credential(rev_reg, max_cred_num, rev_idx, rev_tails_accessor)?;

        trace!("recovery <<< rev_reg_delta {:?}", rev_reg_delta);

        Ok(rev_reg_delta)
    }

    #[allow(dead_code)]
    pub fn recovery<RTA>(&self,
                         rev_reg: &mut RevocationRegistry,
                         max_cred_num: u32,
                         rev_idx: u32,
                         rev_tails_accessor: &RTA) -> IndyResult<RevocationRegistryDelta> where RTA: RevocationTailsAccessor {
        trace!("revoke >>> rev_reg: {:?}, max_cred_num: {:?}, rev_idx: {:?}", rev_reg, max_cred_num, secret!(&rev_idx));

        let rev_reg_delta = CryptoIssuer::recovery_credential(rev_reg, max_cred_num, rev_idx, rev_tails_accessor)?;

        trace!("recovery <<< rev_reg_delta {:?}", rev_reg_delta);

        Ok(rev_reg_delta)
    }
}
<|endoftext|>