<commit_before>use diesel;
use uuid::Uuid;
use diesel::prelude::*;

use data::types::*;
use helpers::db::DB;

use schema::resources;
use schema::resources::dsl as resources_dsl;

/// A model for querying and serializing data from the `resources` table.
#[derive(Debug, Serialize, Deserialize, Identifiable, Queryable, Associations)]
#[belongs_to(pods)]
#[belongs_to(bases)]
pub struct Resource {
    pub name: String,
    pub amount: i64,
    pub max_amount: i64,

    pub id: Uuid,
    pub pod_id: Option<Uuid>,
    pub base_id: Option<Uuid>,
}

impl Resource {
    /// This function adds a new pod into the database and returns the model with the
    /// initialized data.
    pub fn create_pod_resources(pod_id: Uuid, db: &DB) {
        for resource in ResourceTypes::iterator() {
            let new_queue = NewResource {
                name: resource.to_string(),
                amount: 100,
                max_amount: 5000,

                pod_id: Some(pod_id),
                base_id: None,
            };

            diesel::insert(&new_queue)
                .into(resources::table)
                .get_result::<Resource>(&**db)
                .expect("Error inserting new pod resource into database.");
        }
    }

    /// This function checks if there are enough resources for a given set
    /// of costs from a research or model entry.
    /// It also subtracts and updates the resources the specified value from the database.
    ///
    /// - The first parameter is a vector of resources which represent the costs.
    /// - The second parameter is a vector of all `Resource` database models from a pod or a base.
    pub fn check_resources(costs: &Option<Vec<(ResourceTypes, i64)>>,
                           resources: Vec<Resource>,
                           db: &DB)
                           -> bool {
        match costs.as_ref() {
            // There are no costs for this module/research
            None => return true,
            // There are some costs
            Some(costs) => {
                for &(ref resource_type, amount) in costs {
                    // Try to get the correct entry from existing resources.
                    let existing = resources
                        .iter()
                        .filter(|x| x.name == resource_type.to_string())
                        .next();
                    match existing {
                        // There is no resource for this resource_type,
                        // thereby it's not enough.
                        None => return false,
                        // There is a resource for this resource type
                        // We need to check if we got enough of it.
                        Some(existing_resource) => {
                            if existing_resource.amount < amount {
                                return false;
                            }
                        }
                    }
                }
                Resource::update_resources(costs, resources, true, db);
                return true;
            }
        }
    }

    /// This function updates the resources the specified value from the database.
    /// Depending on the third parameter the costs will either be added or subtracted.
    ///
    /// - The first parameter is a vector of resources which represent the costs.
    /// - The second parameter is a vector of all `Resource` database models from a pod or a base.
    /// - The third parameter decides if the amount is to be added or subtracted.
    pub fn update_resources(costs: &Vec<(ResourceTypes, i64)>,
                            resources: Vec<Resource>,
                            subtract: bool,
                            db: &DB) {

        for &(ref resource_type, amount) in costs.iter() {
            // Try to get the correct entry from existing resources.
            let resource = resources
                .iter()
                .filter(|x| x.name == resource_type.to_string())
                .next();
            match resource {
                // There is no resource for this resource_type,
                // thereby it's not enough.
                // There is a resource for this resource type
                Some(resource) => {
                    resource.update_resource(amount, subtract, db);
                }
                None => (),
            }
        }
    }

    /// This function updates a resource in the database.
    ///
    /// - The first parameter is the amount to be added or subtracted.
    /// - The second parameter decides if the amount is to be added or subtracted.
    pub fn update_resource(&self, amount: i64, subtract: bool, db: &DB) {
        let mut new_amount: i64;
        if subtract {
            new_amount = self.amount - amount;
        } else {
            new_amount = self.amount + amount;
            if new_amount > self.max_amount {
                new_amount = self.max_amount;
            }
        }

        let updated_resource = UpdatedResource {
            amount: Some(new_amount),
            max_amount: None,
        };

        diesel::update(resources_dsl::resources.filter(resources_dsl::id.eq(self.id)))
            .set(&updated_resource)
            .get_result::<Resource>(&**db)
            .expect("Failed to update resource.");
    }
}

/// A model to create a new database instance of in the resource table.
#[derive(Insertable)]
#[table_name="resources"]
pub struct NewResource {
    pub name: String,
    pub amount: i64,
    pub max_amount: i64,
    pub pod_id: Option<Uuid>,
    pub base_id: Option<Uuid>,
}

/// Changeset for Resources.
#[derive(AsChangeset)]
#[table_name="resources"]
pub struct UpdatedResource {
    pub amount: Option<i64>,
    pub max_amount: Option<i64>,
}
<commit_msg>Use batch insert for resources<commit_after>use diesel;
use uuid::Uuid;
use diesel::prelude::*;

use data::types::*;
use helpers::db::DB;

use schema::resources;
use schema::resources::dsl as resources_dsl;

/// A model for querying and serializing data from the `resources` table.
#[derive(Debug, Serialize, Deserialize, Identifiable, Queryable, Associations)]
#[belongs_to(pods)]
#[belongs_to(bases)]
pub struct Resource {
    pub name: String,
    pub amount: i64,
    pub max_amount: i64,

    pub id: Uuid,
    pub pod_id: Option<Uuid>,
    pub base_id: Option<Uuid>,
}

impl Resource {
    /// This function adds a new pod into the database and returns the model with the
    /// initialized data.
    pub fn create_pod_resources(pod_id: Uuid, db: &DB) {
        let mut resources: Vec<NewResource> = Vec::new();
        for resource in ResourceTypes::iterator() {
            resources.push(NewResource {
                name: resource.to_string(),
                amount: 100,
                max_amount: 5000,

                pod_id: Some(pod_id),
                base_id: None,
            });
        }

        diesel::insert(&resources)
            .into(resources::table)
            .execute(&**db)
            .expect("Error inserting new pod resource into database.");

    }

    /// This function checks if there are enough resources for a given set
    /// of costs from a research or model entry.
    /// It also subtracts and updates the resources the specified value from the database.
    ///
    /// - The first parameter is a vector of resources which represent the costs.
    /// - The second parameter is a vector of all `Resource` database models from a pod or a base.
    pub fn check_resources(costs: &Option<Vec<(ResourceTypes, i64)>>,
                           resources: Vec<Resource>,
                           db: &DB)
                           -> bool {
        match costs.as_ref() {
            // There are no costs for this module/research
            None => return true,
            // There are some costs
            Some(costs) => {
                for &(ref resource_type, amount) in costs {
                    // Try to get the correct entry from existing resources.
                    let existing = resources
                        .iter()
                        .filter(|x| x.name == resource_type.to_string())
                        .next();
                    match existing {
                        // There is no resource for this resource_type,
                        // thereby it's not enough.
                        None => return false,
                        // There is a resource for this resource type
                        // We need to check if we got enough of it.
                        Some(existing_resource) => {
                            if existing_resource.amount < amount {
                                return false;
                            }
                        }
                    }
                }
                Resource::update_resources(costs, resources, true, db);
                return true;
            }
        }
    }

    /// This function updates the resources the specified value from the database.
    /// Depending on the third parameter the costs will either be added or subtracted.
    ///
    /// - The first parameter is a vector of resources which represent the costs.
    /// - The second parameter is a vector of all `Resource` database models from a pod or a base.
    /// - The third parameter decides if the amount is to be added or subtracted.
    pub fn update_resources(costs: &Vec<(ResourceTypes, i64)>,
                            resources: Vec<Resource>,
                            subtract: bool,
                            db: &DB) {

        for &(ref resource_type, amount) in costs.iter() {
            // Try to get the correct entry from existing resources.
            let resource = resources
                .iter()
                .filter(|x| x.name == resource_type.to_string())
                .next();
            match resource {
                // There is no resource for this resource_type,
                // thereby it's not enough.
                // There is a resource for this resource type
                Some(resource) => {
                    resource.update_resource(amount, subtract, db);
                }
                None => (),
            }
        }
    }

    /// This function updates a resource in the database.
    ///
    /// - The first parameter is the amount to be added or subtracted.
    /// - The second parameter decides if the amount is to be added or subtracted.
    pub fn update_resource(&self, amount: i64, subtract: bool, db: &DB) {
        let mut new_amount: i64;
        if subtract {
            new_amount = self.amount - amount;
        } else {
            new_amount = self.amount + amount;
            if new_amount > self.max_amount {
                new_amount = self.max_amount;
            }
        }

        let updated_resource = UpdatedResource {
            amount: Some(new_amount),
            max_amount: None,
        };

        diesel::update(resources_dsl::resources.filter(resources_dsl::id.eq(self.id)))
            .set(&updated_resource)
            .get_result::<Resource>(&**db)
            .expect("Failed to update resource.");
    }
}

/// A model to create a new database instance of in the resource table.
#[derive(Insertable)]
#[table_name="resources"]
pub struct NewResource {
    pub name: String,
    pub amount: i64,
    pub max_amount: i64,
    pub pod_id: Option<Uuid>,
    pub base_id: Option<Uuid>,
}

/// Changeset for Resources.
#[derive(AsChangeset)]
#[table_name="resources"]
pub struct UpdatedResource {
    pub amount: Option<i64>,
    pub max_amount: Option<i64>,
}
<|endoftext|>


<commit_before>use std::fmt::Debug;

use num::Zero;

use {Point2f, Point3f, Transform, Vector2f, Vector3f};
use interaction::SurfaceInteraction;
use spectrum::Spectrum;

mod checkerboard;
mod constant;
mod fbm;
mod imagemap;
mod mix;
mod scale;
mod uv;

pub use self::checkerboard::CheckerboardTexture;
pub use self::constant::ConstantTexture;
pub use self::fbm::FbmTexture;
pub use self::imagemap::ImageTexture;
pub use self::mix::MixTexture;
pub use self::scale::ScaleTexture;
pub use self::uv::UVTexture;

pub trait Texture<T>: Debug + Send + Sync {
    fn evaluate(&self, si: &SurfaceInteraction) -> T;
}

// Some convenient aliases
pub type TextureSpectrum = Texture<Spectrum>;
pub type TextureFloat = Texture<f32>;

// Texture mappings

pub trait TextureMapping2D: Debug + Send + Sync {
    fn map(&self, si: &SurfaceInteraction) -> (Point2f, Vector2f, Vector2f);
}

#[derive(Debug)]
pub struct UVMapping2D {
    su: f32,
    sv: f32,
    du: f32,
    dv: f32,
}

impl UVMapping2D {
    pub fn new(su: f32, sv: f32, du: f32, dv: f32) -> UVMapping2D {
        UVMapping2D {
            su: su,
            sv: sv,
            du: du,
            dv: dv,
        }
    }
}

impl TextureMapping2D for UVMapping2D {
    fn map(&self, si: &SurfaceInteraction) -> (Point2f, Vector2f, Vector2f) {
        (
            Point2f::new(self.su * si.uv.x + self.du, self.sv * si.uv.y + self.dv),
            Vector2f::zero(),
            Vector2f::zero(),
        )
    }
}

#[derive(Debug)]
struct PlanarMapping2D {
    vs: Vector3f,
    vt: Vector3f,
    ds: f32,
    dt: f32,
}

impl PlanarMapping2D {
    pub fn new(vs: Vector3f, vt: Vector3f, ds: f32, dt: f32) -> PlanarMapping2D {
        PlanarMapping2D { vs, vt, ds, dt }
    }
}

impl TextureMapping2D for PlanarMapping2D {
    fn map(&self, si: &SurfaceInteraction) -> (Point2f, Vector2f, Vector2f) {
        let vec = Vector3f::from(si.hit.p);
        (
            Point2f::new(self.ds + vec.dot(&self.vs), self.dt + vec.dot(&self.vt)),
            Vector2f::new(si.dpdx.dot(&self.vs), si.dpdx.dot(&self.vt)),
            Vector2f::new(si.dpdy.dot(&self.vs), si.dpdy.dot(&self.vt)),
        )
    }
}

pub trait TextureMapping3D: Debug + Send + Sync {
    fn map(&self, si: &SurfaceInteraction) -> (Point3f, Vector3f, Vector3f);
}

#[derive(Debug, Default)]
pub struct IdentityMapping3D {
    world_to_texture: Transform,
}

impl IdentityMapping3D {
    pub fn new(tex2world: Transform) -> IdentityMapping3D {
        IdentityMapping3D {
            world_to_texture: tex2world,
        }
    }
}

impl TextureMapping3D for IdentityMapping3D {
    fn map(&self, si: &SurfaceInteraction) -> (Point3f, Vector3f, Vector3f) {
        let dpdx = &self.world_to_texture * &si.dpdx;
        let dpdy = &self.world_to_texture * &si.dpdy;
        let p = &self.world_to_texture * &si.hit.p;

        (p, dpdx, dpdy)
    }
}
<commit_msg>Returns proper dstdx and dstdy from UVMapping2D::map()<commit_after>use std::fmt::Debug;

use num::Zero;

use {Point2f, Point3f, Transform, Vector2f, Vector3f};
use interaction::SurfaceInteraction;
use spectrum::Spectrum;

mod checkerboard;
mod constant;
mod fbm;
mod imagemap;
mod mix;
mod scale;
mod uv;

pub use self::checkerboard::CheckerboardTexture;
pub use self::constant::ConstantTexture;
pub use self::fbm::FbmTexture;
pub use self::imagemap::ImageTexture;
pub use self::mix::MixTexture;
pub use self::scale::ScaleTexture;
pub use self::uv::UVTexture;

pub trait Texture<T>: Debug + Send + Sync {
    fn evaluate(&self, si: &SurfaceInteraction) -> T;
}

// Some convenient aliases
pub type TextureSpectrum = Texture<Spectrum>;
pub type TextureFloat = Texture<f32>;

// Texture mappings

pub trait TextureMapping2D: Debug + Send + Sync {
    fn map(&self, si: &SurfaceInteraction) -> (Point2f, Vector2f, Vector2f);
}

#[derive(Debug)]
pub struct UVMapping2D {
    su: f32,
    sv: f32,
    du: f32,
    dv: f32,
}

impl UVMapping2D {
    pub fn new(su: f32, sv: f32, du: f32, dv: f32) -> UVMapping2D {
        UVMapping2D {
            su: su,
            sv: sv,
            du: du,
            dv: dv,
        }
    }
}

impl TextureMapping2D for UVMapping2D {
    fn map(&self, si: &SurfaceInteraction) -> (Point2f, Vector2f, Vector2f) {
        (
            Point2f::new(self.su * si.uv.x + self.du, self.sv * si.uv.y + self.dv),
            // dstdx
            Vector2f::new(self.su * si.dudx, self.dv * si.dvdx),
            // dstdy
            Vector2f::new(self.su * si.dudy, self.dv * si.dvdy),
        )
    }
}

#[derive(Debug)]
struct PlanarMapping2D {
    vs: Vector3f,
    vt: Vector3f,
    ds: f32,
    dt: f32,
}

impl PlanarMapping2D {
    pub fn new(vs: Vector3f, vt: Vector3f, ds: f32, dt: f32) -> PlanarMapping2D {
        PlanarMapping2D { vs, vt, ds, dt }
    }
}

impl TextureMapping2D for PlanarMapping2D {
    fn map(&self, si: &SurfaceInteraction) -> (Point2f, Vector2f, Vector2f) {
        let vec = Vector3f::from(si.hit.p);
        (
            Point2f::new(self.ds + vec.dot(&self.vs), self.dt + vec.dot(&self.vt)),
            Vector2f::new(si.dpdx.dot(&self.vs), si.dpdx.dot(&self.vt)),
            Vector2f::new(si.dpdy.dot(&self.vs), si.dpdy.dot(&self.vt)),
        )
    }
}

pub trait TextureMapping3D: Debug + Send + Sync {
    fn map(&self, si: &SurfaceInteraction) -> (Point3f, Vector3f, Vector3f);
}

#[derive(Debug, Default)]
pub struct IdentityMapping3D {
    world_to_texture: Transform,
}

impl IdentityMapping3D {
    pub fn new(tex2world: Transform) -> IdentityMapping3D {
        IdentityMapping3D {
            world_to_texture: tex2world,
        }
    }
}

impl TextureMapping3D for IdentityMapping3D {
    fn map(&self, si: &SurfaceInteraction) -> (Point3f, Vector3f, Vector3f) {
        let dpdx = &self.world_to_texture * &si.dpdx;
        let dpdy = &self.world_to_texture * &si.dpdy;
        let p = &self.world_to_texture * &si.hit.p;

        (p, dpdx, dpdy)
    }
}
<|endoftext|>


<commit_before>use super::ipv4_header::IPv4Header;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::source_destination::SourceDestination;
use super::transport_header::TransportHeader;

/// Convert from level 5 to level 3 by appending correct IP and transport headers.
pub struct Packetizer {
    buffer: Box<[u8; MAX_PACKET_LENGTH]>,
    transport_index: usize,
    payload_index: usize,
    ipv4_header: IPv4Header,
    transport_header: TransportHeader,
}

impl Packetizer {
    pub fn new(raw: &mut [u8], mut ipv4_header: IPv4Header, mut transport_header: TransportHeader) -> Self {
        let mut buffer = Box::new([0; MAX_PACKET_LENGTH]);

        let mut ipv4_header = ipv4_header.clone();
        let mut transport_header = transport_header.clone();

        let transport_index = ipv4_header.header_length as usize;
        let payload_index = transport_index + transport_header.get_header_length() as usize;
        &mut buffer[..payload_index].copy_from_slice(&raw[..payload_index]);

        ipv4_header.switch_source_and_destination(&mut buffer[..]);
        transport_header.switch_source_and_destination(&mut buffer[transport_index..]);

        Self {
            buffer: buffer,
            transport_index: transport_index,
            payload_index: payload_index,
            ipv4_header: ipv4_header,
            transport_header: transport_header,
        }
    }

    pub fn packetize_empty_payload(&mut self) -> IPv4Packet {
        self.inflate(0)
    }

    fn inflate(&mut self, payload_length: u16) -> IPv4Packet {
        let total_length = self.payload_index as u16 + payload_length;

        self.ipv4_header.set_total_length(&mut self.buffer[..], total_length);
        self.transport_header.set_payload_length(&mut self.buffer[self.transport_index..], payload_length);

        let mut ipv4_packet = IPv4Packet::new(&mut self.buffer[..total_length as usize], self.ipv4_header, self.transport_header);
        ipv4_packet.compute_checksums();
        ipv4_packet
    }
}
<commit_msg>Implement Packetizer.packetize()<commit_after>use std::io;
use super::ipv4_header::IPv4Header;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::source_destination::SourceDestination;
use super::transport_header::TransportHeader;

/// Convert from level 5 to level 3 by appending correct IP and transport headers.
pub struct Packetizer {
    buffer: Box<[u8; MAX_PACKET_LENGTH]>,
    transport_index: usize,
    payload_index: usize,
    ipv4_header: IPv4Header,
    transport_header: TransportHeader,
}

impl Packetizer {
    pub fn new(raw: &mut [u8], mut ipv4_header: IPv4Header, mut transport_header: TransportHeader) -> Self {
        let mut buffer = Box::new([0; MAX_PACKET_LENGTH]);

        let mut ipv4_header = ipv4_header.clone();
        let mut transport_header = transport_header.clone();

        let transport_index = ipv4_header.header_length as usize;
        let payload_index = transport_index + transport_header.get_header_length() as usize;
        &mut buffer[..payload_index].copy_from_slice(&raw[..payload_index]);

        ipv4_header.switch_source_and_destination(&mut buffer[..]);
        transport_header.switch_source_and_destination(&mut buffer[transport_index..]);

        Self {
            buffer: buffer,
            transport_index: transport_index,
            payload_index: payload_index,
            ipv4_header: ipv4_header,
            transport_header: transport_header,
        }
    }

    pub fn packetize_empty_payload(&mut self) -> IPv4Packet {
        self.inflate(0)
    }

    pub fn packetize_chunk<R: io::Read>(&mut self, source: &mut R, max_chunk_size: usize) -> io::Result<IPv4Packet> {
        assert!(max_chunk_size <= self.buffer.len() - self.payload_index);
        let range = self.payload_index..self.payload_index + max_chunk_size;
        let r = source.read(&mut self.buffer[range])?;
        let ipv4_packet = self.inflate(r as u16);
        Ok(ipv4_packet)
    }

    pub fn packetize<R: io::Read>(&mut self, source: &mut R) -> io::Result<IPv4Packet> {
        let payload_max_length = self.buffer.len() - self.payload_index;
        self.packetize_chunk(source, payload_max_length)
    }

    fn inflate(&mut self, payload_length: u16) -> IPv4Packet {
        let total_length = self.payload_index as u16 + payload_length;

        self.ipv4_header.set_total_length(&mut self.buffer[..], total_length);
        self.transport_header.set_payload_length(&mut self.buffer[self.transport_index..], payload_length);

        let mut ipv4_packet = IPv4Packet::new(&mut self.buffer[..total_length as usize], self.ipv4_header, self.transport_header);
        ipv4_packet.compute_checksums();
        ipv4_packet
    }
}
<|endoftext|>


<commit_before>//! Defines the `TimeManager` trait.

use uci::SetOption;
use hash_table::Variation;
use search::*;

/// Describes the remaining time on the clocks.
#[derive(Clone, Debug)]
pub struct RemainingTime {
    /// The remaining time in milliseconds for white.
    pub white_millis: u64,

    /// The remaining time in milliseconds for black.
    pub black_millis: u64,

    /// The number of milliseconds with which white's remaining time
    /// is incremented on each move.
    pub winc_millis: u64,

    /// The number of milliseconds with which black's remaining time
    /// is incremented on each move.
    pub binc_millis: u64,

    /// The number of moves to the next time control.
    ///
    /// Can not be zero.
    pub movestogo: Option<u64>,
}

/// A trait for deciding when the search must be terminated and the
/// best move played.
pub trait TimeManager<T: DeepeningSearch<ReportData = Vec<Variation>>>
    : SetOption {
    /// Creates a new instance.
    ///
    /// * `position` gives the current position.
    ///
    /// * `time` gives the remaining time on the clocks.
    fn new(position: &T::SearchNode, time: &RemainingTime) -> Self;

    /// Returns `true` if the search must be terminated and the best
    /// move played.
    ///
    /// * `search_instance` is a mutable reference to the running
    ///   search instance. The time manager should be careful when
    ///   calling methods on the currently running search instance, so
    ///   as not to disturb its normal working. In particular,
    ///   `start_search` and `try_recv_report` methods must not be
    ///   called, and a `"TERMINATE"` message must not be sent.
    ///
    /// * `report`, when supplied, gives a reference to an incoming
    ///   search progress report. `must_play` will be called exactly
    ///   once for each progress report generated by the search,
    ///   following the order in which the reports have been
    ///   generated.
    fn must_play(&mut self,
                 search_instance: &mut T,
                 report: Option<&SearchReport<Vec<Variation>>>)
                 -> bool;
}
<commit_msg>minor doc fix<commit_after>//! Defines the `TimeManager` trait.

use uci::SetOption;
use hash_table::Variation;
use search::*;

/// Describes the remaining time on the clocks.
#[derive(Clone, Debug)]
pub struct RemainingTime {
    /// The remaining time in milliseconds for white.
    pub white_millis: u64,

    /// The remaining time in milliseconds for black.
    pub black_millis: u64,

    /// The number of milliseconds with which white's remaining time
    /// is incremented on each move.
    pub winc_millis: u64,

    /// The number of milliseconds with which black's remaining time
    /// is incremented on each move.
    pub binc_millis: u64,

    /// The number of moves to the next time control.
    ///
    /// Can not be zero.
    pub movestogo: Option<u64>,
}

/// A trait for deciding when the search must be terminated and the
/// best move played.
pub trait TimeManager<T: DeepeningSearch<ReportData = Vec<Variation>>>
    : SetOption {
    /// Creates a new instance.
    ///
    /// * `position` gives the current position.
    ///
    /// * `time` gives the remaining time on the clocks.
    fn new(position: &T::SearchNode, time: &RemainingTime) -> Self;

    /// Returns `true` if the search must be terminated and the best
    /// move played.
    ///
    /// * `search_instance` is a mutable reference to the currently
    ///   running search instance. The time manager should be careful
    ///   when calling methods on the currently running search
    ///   instance, so as not to disturb its normal working. In
    ///   particular, `start_search` and `try_recv_report` methods
    ///   must not be called, and a `"TERMINATE"` message must not be
    ///   sent.
    ///
    /// * `report`, when supplied, gives a reference to an incoming
    ///   search progress report. `must_play` will be called exactly
    ///   once for each progress report generated by the search,
    ///   following the order in which the reports have been
    ///   generated.
    fn must_play(&mut self,
                 search_instance: &mut T,
                 report: Option<&SearchReport<Vec<Variation>>>)
                 -> bool;
}
<|endoftext|>


<commit_before>

use types::cursor::XCursorImage;

use wayland_sys::server::WAYLAND_SERVER_HANDLE;
use wlroots_sys::{wl_list, wlr_output, wlr_output_events, wlr_output_layout,
                  wlr_output_layout_add_auto, wlr_output_layout_create, wlr_output_layout_destroy,
                  wlr_output_layout_remove, wlr_output_make_current, wlr_output_mode,
                  wlr_output_set_cursor, wlr_output_set_mode, wlr_output_swap_buffers};

use std::cell::RefCell;
use std::ffi::CStr;
use std::rc::Rc;

pub struct OutputState {
    pub layout: Option<Rc<RefCell<OutputLayout>>>
}

/// A wrapper around a wlr_output.
#[derive(Debug)]
pub struct Output {
    output: *mut wlr_output
}

#[derive(Debug)]
pub struct OutputLayout {
    layout: *mut wlr_output_layout
}

impl Output {
    pub unsafe fn set_user_data(&mut self, data: Rc<OutputState>) {
        (*self.output).data = Rc::into_raw(data) as *mut _
    }

    pub unsafe fn user_data(&mut self) -> *mut OutputState {
        (*self.output).data as *mut _
    }

    // TODO Prove all of this is sound, including user_data
    pub unsafe fn layout(&mut self) -> Option<Rc<RefCell<OutputLayout>>> {
        let data = self.user_data();
        if data.is_null() {
            None
        } else {
            (*data).layout.clone()
        }
    }

    pub fn add_layout_auto(&mut self, layout: Rc<RefCell<OutputLayout>>) {
        unsafe {
            wlr_output_layout_add_auto(layout.borrow_mut().to_ptr(), self.output);
            let user_data = self.user_data();
            if user_data.is_null() {
                self.set_user_data(Rc::new(OutputState {
                    layout: Some(layout)
                }));
            } else {
                (*user_data).layout = Some(layout);
            }
        }
    }

    pub fn set_cursor<'cursor>(&mut self, image: &'cursor XCursorImage<'cursor>) -> Result<(), ()> {
        unsafe {
            match wlr_output_set_cursor(self.output,
                                        image.buffer.as_ptr(),
                                        image.width as i32,
                                        image.width,
                                        image.height,
                                        image.hotspot_x as i32,
                                        image.hotspot_y as i32)
            {
                true => Ok(()),
                false => Err(())
            }
        }
    }

    /// Sets the best modesetting for an output.
    pub fn choose_best_mode(&mut self) {
        unsafe {
            let length = ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_list_length, self.modes() as _);
            if length > 0 {
                // TODO Better logging
                wlr_log!(L_DEBUG, "output added {:?}", self);
                let first_mode_ptr: *mut wlr_output_mode;
                first_mode_ptr = container_of!(&mut (*(*self.modes()).prev) as *mut _,
                                               wlr_output_mode,
                                               link);
                wlr_output_set_mode(self.to_ptr(), first_mode_ptr);
            }
        }
    }

    /// Gets the name of the output in UTF-8.
    pub fn name(&self) -> String {
        unsafe {
            CStr::from_ptr((*self.output).name.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Gets the make of the output in UTF-8.
    pub fn make(&self) -> String {
        unsafe {
            CStr::from_ptr((*self.output).make.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Gets the model of the output in UTF-8.
    pub fn model(&self) -> String {
        unsafe {
            CStr::from_ptr((*self.output).model.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    pub fn make_current(&mut self) {
        unsafe { wlr_output_make_current(self.output) }
    }

    pub fn swap_buffers(&mut self) {
        unsafe { wlr_output_swap_buffers(self.output) }
    }

    /// Get the dimensions of the output as (width, height).
    pub fn dimensions(&self) -> (i32, i32) {
        unsafe { ((*self.output).width, (*self.output).height) }
    }

    /// Get the physical dimensions of the output as (width, height).
    pub fn physical_dimensions(&self) -> (i32, i32) {
        unsafe { ((*self.output).phys_width, (*self.output).phys_height) }
    }

    // TODO Wrap this somehow? Hmm
    pub unsafe fn modes(&self) -> *mut wl_list {
        &mut (*self.output).modes
    }

    pub unsafe fn events(&self) -> wlr_output_events {
        (*self.output).events
    }

    pub unsafe fn from_ptr(output: *mut wlr_output) -> Self {
        Output { output }
    }

    pub unsafe fn to_ptr(&self) -> *mut wlr_output {
        self.output
    }
}

impl OutputLayout {
    pub fn new() -> Self {
        unsafe {
            OutputLayout {
                layout: wlr_output_layout_create()
            }
        }
    }

    pub unsafe fn to_ptr(&self) -> *mut wlr_output_layout {
        self.layout
    }

    pub unsafe fn from_ptr(layout: *mut wlr_output_layout) -> Self {
        OutputLayout { layout }
    }

    pub fn remove(&mut self, output: &mut Output) {
        // TODO Double check we can pass any output in here and not cause unsafety
        unsafe { wlr_output_layout_remove(self.layout, output.to_ptr()) }
    }
}

impl Drop for OutputLayout {
    fn drop(&mut self) {
        unsafe { wlr_output_layout_destroy(self.layout) }
    }
}
<commit_msg>Added TODO for output drop<commit_after>

use types::cursor::XCursorImage;

use wayland_sys::server::WAYLAND_SERVER_HANDLE;
use wlroots_sys::{wl_list, wlr_output, wlr_output_events, wlr_output_layout,
                  wlr_output_layout_add_auto, wlr_output_layout_create, wlr_output_layout_destroy,
                  wlr_output_layout_remove, wlr_output_make_current, wlr_output_mode,
                  wlr_output_set_cursor, wlr_output_set_mode, wlr_output_swap_buffers};

use std::cell::RefCell;
use std::ffi::CStr;
use std::rc::Rc;

pub struct OutputState {
    pub layout: Option<Rc<RefCell<OutputLayout>>>
}

/// A wrapper around a wlr_output.
#[derive(Debug)]
pub struct Output {
    output: *mut wlr_output
}

#[derive(Debug)]
pub struct OutputLayout {
    layout: *mut wlr_output_layout
}

impl Output {
    pub unsafe fn set_user_data(&mut self, data: Rc<OutputState>) {
        (*self.output).data = Rc::into_raw(data) as *mut _
    }

    pub unsafe fn user_data(&mut self) -> *mut OutputState {
        (*self.output).data as *mut _
    }

    // TODO Prove all of this is sound, including user_data
    pub unsafe fn layout(&mut self) -> Option<Rc<RefCell<OutputLayout>>> {
        let data = self.user_data();
        if data.is_null() {
            None
        } else {
            (*data).layout.clone()
        }
    }

    pub fn add_layout_auto(&mut self, layout: Rc<RefCell<OutputLayout>>) {
        unsafe {
            wlr_output_layout_add_auto(layout.borrow_mut().to_ptr(), self.output);
            let user_data = self.user_data();
            if user_data.is_null() {
                self.set_user_data(Rc::new(OutputState {
                    layout: Some(layout)
                }));
            } else {
                (*user_data).layout = Some(layout);
            }
        }
    }

    pub fn set_cursor<'cursor>(&mut self, image: &'cursor XCursorImage<'cursor>) -> Result<(), ()> {
        unsafe {
            match wlr_output_set_cursor(self.output,
                                        image.buffer.as_ptr(),
                                        image.width as i32,
                                        image.width,
                                        image.height,
                                        image.hotspot_x as i32,
                                        image.hotspot_y as i32)
            {
                true => Ok(()),
                false => Err(())
            }
        }
    }

    /// Sets the best modesetting for an output.
    pub fn choose_best_mode(&mut self) {
        unsafe {
            let length = ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_list_length, self.modes() as _);
            if length > 0 {
                // TODO Better logging
                wlr_log!(L_DEBUG, "output added {:?}", self);
                let first_mode_ptr: *mut wlr_output_mode;
                first_mode_ptr = container_of!(&mut (*(*self.modes()).prev) as *mut _,
                                               wlr_output_mode,
                                               link);
                wlr_output_set_mode(self.to_ptr(), first_mode_ptr);
            }
        }
    }

    /// Gets the name of the output in UTF-8.
    pub fn name(&self) -> String {
        unsafe {
            CStr::from_ptr((*self.output).name.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Gets the make of the output in UTF-8.
    pub fn make(&self) -> String {
        unsafe {
            CStr::from_ptr((*self.output).make.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Gets the model of the output in UTF-8.
    pub fn model(&self) -> String {
        unsafe {
            CStr::from_ptr((*self.output).model.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    pub fn make_current(&mut self) {
        unsafe { wlr_output_make_current(self.output) }
    }

    pub fn swap_buffers(&mut self) {
        unsafe { wlr_output_swap_buffers(self.output) }
    }

    /// Get the dimensions of the output as (width, height).
    pub fn dimensions(&self) -> (i32, i32) {
        unsafe { ((*self.output).width, (*self.output).height) }
    }

    /// Get the physical dimensions of the output as (width, height).
    pub fn physical_dimensions(&self) -> (i32, i32) {
        unsafe { ((*self.output).phys_width, (*self.output).phys_height) }
    }

    // TODO Wrap this somehow? Hmm
    pub unsafe fn modes(&self) -> *mut wl_list {
        &mut (*self.output).modes
    }

    pub unsafe fn events(&self) -> wlr_output_events {
        (*self.output).events
    }

    pub unsafe fn from_ptr(output: *mut wlr_output) -> Self {
        Output { output }
    }

    pub unsafe fn to_ptr(&self) -> *mut wlr_output {
        self.output
    }
}

impl Drop for Output {
    fn drop(&mut self) {
        // TODO Implement
        // Also need to make sure it's not dropped except in the remove callback,
        // since right now there's actually a lot of Output destruction which we don't want
        // e.g need to make the from_ptr return ManuallyDrop<Output> now
    }
}

impl OutputLayout {
    pub fn new() -> Self {
        unsafe {
            OutputLayout {
                layout: wlr_output_layout_create()
            }
        }
    }

    pub unsafe fn to_ptr(&self) -> *mut wlr_output_layout {
        self.layout
    }

    pub unsafe fn from_ptr(layout: *mut wlr_output_layout) -> Self {
        OutputLayout { layout }
    }

    pub fn remove(&mut self, output: &mut Output) {
        // TODO Double check we can pass any output in here and not cause unsafety
        unsafe { wlr_output_layout_remove(self.layout, output.to_ptr()) }
    }
}

impl Drop for OutputLayout {
    fn drop(&mut self) {
        unsafe { wlr_output_layout_destroy(self.layout) }
    }
}
<|endoftext|>


<commit_before>//! Module containing the DICOM Transfer Syntax data structure and related methods.
//! Similar to the DcmCodec in DCMTK, the `TransferSyntax` contains all of the necessary
//! algorithms for decoding and encoding DICOM data in a certain transfer syntax.
//!
//! This crate does not host specific transfer syntaxes. Instead, they are created in
//! other crates and registered in the global transfer syntax registry, which implements
//! [`TransferSyntaxIndex`]. For more
//! information, please see the `dicom-transfer-syntax-registry` crate.
//!
//! [`TransferSyntaxIndex`]: ./trait.TransferSyntaxIndex.html

/// Explicit VR Big Endian implementation
#[deprecated(
    since = "0.3.0",
    note = "See `decode::explicit_be` or `encode::explicit_be` instead"
)]
pub mod explicit_be;
/// Explicit VR Little Endian implementation
#[deprecated(
    since = "0.3.0",
    note = "See `decode::explicit_le` or `encode::explicit_le` instead"
)]
pub mod explicit_le;
/// Implicit VR Little Endian implementation
#[deprecated(
    since = "0.3.0",
    note = "See `decode::implicit_le` or `encode::implicit_le` instead"
)]
pub mod implicit_le;

use crate::decode::basic::BasicDecoder;
use crate::decode::DecodeFrom;
use crate::encode::{EncodeTo, EncoderFor};
use std::io::{Read, Write};

pub use byteordered::Endianness;

/// A decoder with its type erased.
pub type DynDecoder<S> = Box<dyn DecodeFrom<S>>;

/// An encoder with its type erased.
pub type DynEncoder<'w, W> = Box<dyn EncodeTo<W> + 'w>;

/// A DICOM transfer syntax specifier. The data RW adapter `A` specifies
/// custom codec capabilities when required.
#[derive(Debug)]
pub struct TransferSyntax<A = DynDataRWAdapter> {
    /// The unique identifier of the transfer syntax.
    uid: &'static str,
    /// The name of the transfer syntax.
    name: &'static str,
    /// The byte order of data.
    byte_order: Endianness,
    /// Whether the transfer syntax mandates an explicit value representation,
    /// or the VR is implicit.
    explicit_vr: bool,
    /// The transfer syntax' requirements and implemented capabilities.
    codec: Codec<A>,
}

#[cfg(feature = "inventory-registry")]
// Collect transfer syntax specifiers from other crates.
inventory::collect!(TransferSyntax);

/// Trait for containers of transfer syntax specifiers.
///
/// Types implementing this trait are held responsible for populating
/// themselves with a set of transfer syntaxes, which can be fully supported,
/// partially supported, or not supported. Usually, only one implementation
/// of this trait is used for the entire program.
pub trait TransferSyntaxIndex {
    /// Obtain a DICOM transfer syntax by its respective UID.
    ///
    /// Implementations of this method should be robust to the possible
    /// presence of a trailing null characters (`\0`) in `uid`.
    fn get(&self, uid: &str) -> Option<&TransferSyntax>;
}

impl<T: ?Sized> TransferSyntaxIndex for &T
where
    T: TransferSyntaxIndex,
{
    fn get(&self, uid: &str) -> Option<&TransferSyntax> {
        (**self).get(uid)
    }
}

#[cfg(feature = "inventory-registry")]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        inventory::submit! {
            ($ts).erased()
        }
    };
}

#[cfg(not(feature = "inventory-registry"))]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
///
/// Without the `inventory-registry` feature, this request is ignored.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        // ignore request
    };
}

/// A description and possible implementation regarding
/// the encoding and decoding requirements of a transfer syntax.
/// This is also used as a means to describe whether pixel data is encapsulated
/// and whether this implementation supports it.
#[derive(Debug, Clone, PartialEq)]
pub enum Codec<A> {
    /// No codec is given, nor is it required.
    None,
    /// Custom encoding and decoding of the entire data set is required, but
    /// not supported. This could be used by a stub of
    /// _Deflated Explicit VR Little Endian_, for example.
    Unsupported,
    /// Custom encoding and decoding of the pixel data set is required, but
    /// not supported. The program should still be able to parse DICOM
    /// data sets and fetch the pixel data in its encapsulated form.
    EncapsulatedPixelData,
    /// A pixel data encapsulation codec is required and provided for reading
    /// and writing pixel data.
    PixelData(A),
    /// A full, custom data set codec is required and provided.
    Dataset(A),
}

/// An alias for a transfer syntax specifier with no pixel data encapsulation
/// nor data set deflating.
pub type AdapterFreeTransferSyntax = TransferSyntax<NeverAdapter>;

/// An adapter of byte read and write streams.
pub trait DataRWAdapter<R, W> {
    /// The type of the adapted reader.
    type Reader: Read;
    /// The type of the adapted writer.
    type Writer: Write;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read;

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write;
}

/// Alias type for a dynamically dispatched data adapter.
pub type DynDataRWAdapter = Box<
    dyn DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        > + Send
        + Sync,
>;

impl<'a, T, R, W> DataRWAdapter<R, W> for &'a T
where
    T: DataRWAdapter<R, W>,
    R: Read,
    W: Write,
{
    type Reader = <T as DataRWAdapter<R, W>>::Reader;
    type Writer = <T as DataRWAdapter<R, W>>::Writer;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read,
    {
        (**self).adapt_reader(reader)
    }

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write,
    {
        (**self).adapt_writer(writer)
    }
}

/** An immaterial type representing an adapted which is never required,
 * and as such is never instantiated. Most transfer syntaxes use this,
 * as they do not have to adapt readers and writers for encoding and decoding.
 */
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum NeverAdapter {}

impl<R, W> DataRWAdapter<R, W> for NeverAdapter {
    type Reader = Box<dyn Read>;
    type Writer = Box<dyn Write>;

    fn adapt_reader(&self, _reader: R) -> Self::Reader
    where
        R: Read,
    {
        unreachable!()
    }

    fn adapt_writer(&self, _writer: W) -> Self::Writer
    where
        W: Write,
    {
        unreachable!()
    }
}

impl<A> TransferSyntax<A> {
    /** Create a new transfer syntax descriptor.
     *
     * Note that only transfer syntax implementors are expected to construct
     * TS descriptors from scratch. For a practical usage of transfer syntaxes,
     * one should look up an existing transfer syntax registry by UID.
     */
    pub const fn new(
        uid: &'static str,
        name: &'static str,
        byte_order: Endianness,
        explicit_vr: bool,
        codec: Codec<A>,
    ) -> Self {
        TransferSyntax {
            uid,
            name,
            byte_order,
            explicit_vr,
            codec,
        }
    }

    /// Obtain this transfer syntax' unique identifier.
    pub const fn uid(&self) -> &'static str {
        self.uid
    }

    /// Obtain the name of this transfer syntax.
    pub const fn name(&self) -> &'static str {
        self.name
    }

    /// Obtain this transfer syntax' expected endianness.
    pub const fn endianness(&self) -> Endianness {
        self.byte_order
    }

    /// Obtain this transfer syntax' codec specification.
    pub fn codec(&self) -> &Codec<A> {
        &self.codec
    }

    /// Check whether this transfer syntax specifier provides a complete
    /// implementation.
    pub fn fully_supported(&self) -> bool {
        matches!(
            self.codec,
            Codec::None | Codec::Dataset(_) | Codec::PixelData(_),
        )
    }

    /// Check whether reading and writing of data sets is unsupported.
    /// If this is `true`, encoding and decoding will not be available.
    pub fn unsupported(&self) -> bool {
        matches!(self.codec, Codec::Unsupported)
    }

    /// Check whether reading and writing the pixel data is unsupported.
    /// If this is `true`, encoding and decoding of the data set will still
    /// be possible, but the pixel data will only be available in its
    /// encapsulated form.
    pub fn unsupported_pixel_encapsulation(&self) -> bool {
        matches!(self.codec, Codec::Unsupported | Codec::EncapsulatedPixelData)
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax.
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder<'s>(&self) -> Option<DynDecoder<dyn Read + 's>> {
        self.decoder_for()
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax
    /// and given reader type (this method is not object safe).
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder_for<S>(&self) -> Option<DynDecoder<S>>
    where
        Self: Sized,
        S: ?Sized + Read,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(
                implicit_le::ImplicitVRLittleEndianDecoder::default(),
            )),
            (Endianness::Little, true) => Some(Box::new(
                explicit_le::ExplicitVRLittleEndianDecoder::default(),
            )),
            (Endianness::Big, true) => {
                Some(Box::new(explicit_be::ExplicitVRBigEndianDecoder::default()))
            }
            _ => None,
        }
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax.
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder<'w>(&self) -> Option<DynEncoder<'w, dyn Write + 'w>> {
        self.encoder_for()
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax
    /// and the given writer type (this method is not object safe).
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder_for<'w, W: 'w>(&self) -> Option<DynEncoder<'w, W>>
    where
        Self: Sized,
        W: ?Sized + Write,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(EncoderFor::new(
                implicit_le::ImplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Little, true) => Some(Box::new(EncoderFor::new(
                explicit_le::ExplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Big, true) => Some(Box::new(EncoderFor::new(
                explicit_be::ExplicitVRBigEndianEncoder::default(),
            ))),
            _ => None,
        }
    }

    /// Obtain a dynamic basic decoder, based on this transfer syntax' expected endianness.
    pub fn basic_decoder(&self) -> BasicDecoder {
        BasicDecoder::from(self.endianness())
    }

    /// Type-erase the pixel data or data set codec.
    pub fn erased(self) -> TransferSyntax
    where
        A: Send + Sync + 'static,
        A: DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        >,
    {
        let codec = match self.codec {
            Codec::Dataset(a) => Codec::Dataset(Box::new(a) as DynDataRWAdapter),
            Codec::PixelData(a) => Codec::PixelData(Box::new(a) as DynDataRWAdapter),
            Codec::EncapsulatedPixelData => Codec::EncapsulatedPixelData,
            Codec::Unsupported => Codec::Unsupported,
            Codec::None => Codec::None,
        };

        TransferSyntax {
            uid: self.uid,
            name: self.name,
            byte_order: self.byte_order,
            explicit_vr: self.explicit_vr,
            codec,
        }
    }
}
<commit_msg>[encoding] Add TransferSyntax::is_codec_free<commit_after>//! Module containing the DICOM Transfer Syntax data structure and related methods.
//! Similar to the DcmCodec in DCMTK, the `TransferSyntax` contains all of the necessary
//! algorithms for decoding and encoding DICOM data in a certain transfer syntax.
//!
//! This crate does not host specific transfer syntaxes. Instead, they are created in
//! other crates and registered in the global transfer syntax registry, which implements
//! [`TransferSyntaxIndex`]. For more
//! information, please see the `dicom-transfer-syntax-registry` crate.
//!
//! [`TransferSyntaxIndex`]: ./trait.TransferSyntaxIndex.html

/// Explicit VR Big Endian implementation
#[deprecated(
    since = "0.3.0",
    note = "See `decode::explicit_be` or `encode::explicit_be` instead"
)]
pub mod explicit_be;
/// Explicit VR Little Endian implementation
#[deprecated(
    since = "0.3.0",
    note = "See `decode::explicit_le` or `encode::explicit_le` instead"
)]
pub mod explicit_le;
/// Implicit VR Little Endian implementation
#[deprecated(
    since = "0.3.0",
    note = "See `decode::implicit_le` or `encode::implicit_le` instead"
)]
pub mod implicit_le;

use crate::decode::basic::BasicDecoder;
use crate::decode::DecodeFrom;
use crate::encode::{EncodeTo, EncoderFor};
use std::io::{Read, Write};

pub use byteordered::Endianness;

/// A decoder with its type erased.
pub type DynDecoder<S> = Box<dyn DecodeFrom<S>>;

/// An encoder with its type erased.
pub type DynEncoder<'w, W> = Box<dyn EncodeTo<W> + 'w>;

/// A DICOM transfer syntax specifier. The data RW adapter `A` specifies
/// custom codec capabilities when required.
#[derive(Debug)]
pub struct TransferSyntax<A = DynDataRWAdapter> {
    /// The unique identifier of the transfer syntax.
    uid: &'static str,
    /// The name of the transfer syntax.
    name: &'static str,
    /// The byte order of data.
    byte_order: Endianness,
    /// Whether the transfer syntax mandates an explicit value representation,
    /// or the VR is implicit.
    explicit_vr: bool,
    /// The transfer syntax' requirements and implemented capabilities.
    codec: Codec<A>,
}

#[cfg(feature = "inventory-registry")]
// Collect transfer syntax specifiers from other crates.
inventory::collect!(TransferSyntax);

/// Trait for containers of transfer syntax specifiers.
///
/// Types implementing this trait are held responsible for populating
/// themselves with a set of transfer syntaxes, which can be fully supported,
/// partially supported, or not supported. Usually, only one implementation
/// of this trait is used for the entire program.
pub trait TransferSyntaxIndex {
    /// Obtain a DICOM transfer syntax by its respective UID.
    ///
    /// Implementations of this method should be robust to the possible
    /// presence of a trailing null characters (`\0`) in `uid`.
    fn get(&self, uid: &str) -> Option<&TransferSyntax>;
}

impl<T: ?Sized> TransferSyntaxIndex for &T
where
    T: TransferSyntaxIndex,
{
    fn get(&self, uid: &str) -> Option<&TransferSyntax> {
        (**self).get(uid)
    }
}

#[cfg(feature = "inventory-registry")]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        inventory::submit! {
            ($ts).erased()
        }
    };
}

#[cfg(not(feature = "inventory-registry"))]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
///
/// Without the `inventory-registry` feature, this request is ignored.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        // ignore request
    };
}

/// A description and possible implementation regarding
/// the encoding and decoding requirements of a transfer syntax.
/// This is also used as a means to describe whether pixel data is encapsulated
/// and whether this implementation supports it.
#[derive(Debug, Clone, PartialEq)]
pub enum Codec<A> {
    /// No codec is given, nor is it required.
    None,
    /// Custom encoding and decoding of the entire data set is required, but
    /// not supported. This could be used by a stub of
    /// _Deflated Explicit VR Little Endian_, for example.
    Unsupported,
    /// Custom encoding and decoding of the pixel data set is required, but
    /// not supported. The program should still be able to parse DICOM
    /// data sets and fetch the pixel data in its encapsulated form.
    EncapsulatedPixelData,
    /// A pixel data encapsulation codec is required and provided for reading
    /// and writing pixel data.
    PixelData(A),
    /// A full, custom data set codec is required and provided.
    Dataset(A),
}

/// An alias for a transfer syntax specifier with no pixel data encapsulation
/// nor data set deflating.
pub type AdapterFreeTransferSyntax = TransferSyntax<NeverAdapter>;

/// An adapter of byte read and write streams.
pub trait DataRWAdapter<R, W> {
    /// The type of the adapted reader.
    type Reader: Read;
    /// The type of the adapted writer.
    type Writer: Write;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read;

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write;
}

/// Alias type for a dynamically dispatched data adapter.
pub type DynDataRWAdapter = Box<
    dyn DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        > + Send
        + Sync,
>;

impl<'a, T, R, W> DataRWAdapter<R, W> for &'a T
where
    T: DataRWAdapter<R, W>,
    R: Read,
    W: Write,
{
    type Reader = <T as DataRWAdapter<R, W>>::Reader;
    type Writer = <T as DataRWAdapter<R, W>>::Writer;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read,
    {
        (**self).adapt_reader(reader)
    }

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write,
    {
        (**self).adapt_writer(writer)
    }
}

/** An immaterial type representing an adapted which is never required,
 * and as such is never instantiated. Most transfer syntaxes use this,
 * as they do not have to adapt readers and writers for encoding and decoding.
 */
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum NeverAdapter {}

impl<R, W> DataRWAdapter<R, W> for NeverAdapter {
    type Reader = Box<dyn Read>;
    type Writer = Box<dyn Write>;

    fn adapt_reader(&self, _reader: R) -> Self::Reader
    where
        R: Read,
    {
        unreachable!()
    }

    fn adapt_writer(&self, _writer: W) -> Self::Writer
    where
        W: Write,
    {
        unreachable!()
    }
}

impl<A> TransferSyntax<A> {
    /** Create a new transfer syntax descriptor.
     *
     * Note that only transfer syntax implementors are expected to construct
     * TS descriptors from scratch. For a practical usage of transfer syntaxes,
     * one should look up an existing transfer syntax registry by UID.
     */
    pub const fn new(
        uid: &'static str,
        name: &'static str,
        byte_order: Endianness,
        explicit_vr: bool,
        codec: Codec<A>,
    ) -> Self {
        TransferSyntax {
            uid,
            name,
            byte_order,
            explicit_vr,
            codec,
        }
    }

    /// Obtain this transfer syntax' unique identifier.
    pub const fn uid(&self) -> &'static str {
        self.uid
    }

    /// Obtain the name of this transfer syntax.
    pub const fn name(&self) -> &'static str {
        self.name
    }

    /// Obtain this transfer syntax' expected endianness.
    pub const fn endianness(&self) -> Endianness {
        self.byte_order
    }

    /// Obtain this transfer syntax' codec specification.
    pub fn codec(&self) -> &Codec<A> {
        &self.codec
    }

    /// Check whether this transfer syntax specifier provides a complete
    /// implementation.
    pub fn fully_supported(&self) -> bool {
        matches!(
            self.codec,
            Codec::None | Codec::Dataset(_) | Codec::PixelData(_),
        )
    }

    /// Check whether no codecs are required for this transfer syntax,
    /// meaning that a complete implementation is available
    /// and no pixel data conversion is required.
    pub fn is_codec_free(&self) -> bool {
        matches!(self.codec, Codec::None)
    }

    /// Check whether reading and writing of data sets is unsupported.
    /// If this is `true`, encoding and decoding will not be available.
    pub fn unsupported(&self) -> bool {
        matches!(self.codec, Codec::Unsupported)
    }

    /// Check whether reading and writing the pixel data is unsupported.
    /// If this is `true`, encoding and decoding of the data set will still
    /// be possible, but the pixel data will only be available in its
    /// encapsulated form.
    pub fn unsupported_pixel_encapsulation(&self) -> bool {
        matches!(self.codec, Codec::Unsupported | Codec::EncapsulatedPixelData)
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax.
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder<'s>(&self) -> Option<DynDecoder<dyn Read + 's>> {
        self.decoder_for()
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax
    /// and given reader type (this method is not object safe).
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder_for<S>(&self) -> Option<DynDecoder<S>>
    where
        Self: Sized,
        S: ?Sized + Read,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(
                implicit_le::ImplicitVRLittleEndianDecoder::default(),
            )),
            (Endianness::Little, true) => Some(Box::new(
                explicit_le::ExplicitVRLittleEndianDecoder::default(),
            )),
            (Endianness::Big, true) => {
                Some(Box::new(explicit_be::ExplicitVRBigEndianDecoder::default()))
            }
            _ => None,
        }
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax.
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder<'w>(&self) -> Option<DynEncoder<'w, dyn Write + 'w>> {
        self.encoder_for()
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax
    /// and the given writer type (this method is not object safe).
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder_for<'w, W: 'w>(&self) -> Option<DynEncoder<'w, W>>
    where
        Self: Sized,
        W: ?Sized + Write,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(EncoderFor::new(
                implicit_le::ImplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Little, true) => Some(Box::new(EncoderFor::new(
                explicit_le::ExplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Big, true) => Some(Box::new(EncoderFor::new(
                explicit_be::ExplicitVRBigEndianEncoder::default(),
            ))),
            _ => None,
        }
    }

    /// Obtain a dynamic basic decoder, based on this transfer syntax' expected endianness.
    pub fn basic_decoder(&self) -> BasicDecoder {
        BasicDecoder::from(self.endianness())
    }

    /// Type-erase the pixel data or data set codec.
    pub fn erased(self) -> TransferSyntax
    where
        A: Send + Sync + 'static,
        A: DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        >,
    {
        let codec = match self.codec {
            Codec::Dataset(a) => Codec::Dataset(Box::new(a) as DynDataRWAdapter),
            Codec::PixelData(a) => Codec::PixelData(Box::new(a) as DynDataRWAdapter),
            Codec::EncapsulatedPixelData => Codec::EncapsulatedPixelData,
            Codec::Unsupported => Codec::Unsupported,
            Codec::None => Codec::None,
        };

        TransferSyntax {
            uid: self.uid,
            name: self.name,
            byte_order: self.byte_order,
            explicit_vr: self.explicit_vr,
            codec,
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::conversion::{
    analysis::fun::function_wrapper::{CppConversionType, TypeConversionPolicy},
    ConvertError,
};

use super::type_to_cpp::{type_to_cpp, CppNameMap};

impl TypeConversionPolicy {
    pub(super) fn unconverted_type(
        &self,
        cpp_name_map: &CppNameMap,
    ) -> Result<String, ConvertError> {
        match self.cpp_conversion {
            CppConversionType::FromUniquePtrToValue => self.unique_ptr_wrapped_type(cpp_name_map),
            CppConversionType::FromPtrToValue => {
                Ok(format!("{}*", self.unwrapped_type_as_string(cpp_name_map)?))
            }
            _ => self.unwrapped_type_as_string(cpp_name_map),
        }
    }

    pub(super) fn converted_type(&self, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
        match self.cpp_conversion {
            CppConversionType::FromValueToUniquePtr => self.unique_ptr_wrapped_type(cpp_name_map),
            _ => self.unwrapped_type_as_string(cpp_name_map),
        }
    }

    fn unwrapped_type_as_string(&self, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
        type_to_cpp(&self.unwrapped_type, cpp_name_map)
    }

    fn unique_ptr_wrapped_type(
        &self,
        original_name_map: &CppNameMap,
    ) -> Result<String, ConvertError> {
        Ok(format!(
            "std::unique_ptr<{}>",
            self.unwrapped_type_as_string(original_name_map)?
        ))
    }

    pub(super) fn cpp_conversion(
        &self,
        var_name: &str,
        cpp_name_map: &CppNameMap,
        is_return: bool,
    ) -> Result<String, ConvertError> {
        // If is_return we want to avoid unnecessary std::moves because they
        // make RVO less effective
        Ok(match self.cpp_conversion {
            CppConversionType::None => {
                if is_return {
                    var_name.to_string()
                } else {
                    format!("std::move({})", var_name)
                }
            }
            CppConversionType::FromUniquePtrToValue | CppConversionType::FromPtrToMove => {
                format!("std::move(*{})", var_name)
            }
            CppConversionType::FromValueToUniquePtr => format!(
                "std::make_unique<{}>({})",
                self.unconverted_type(cpp_name_map)?,
                var_name
            ),
            CppConversionType::FromPtrToValue => {
                let dereference = format!("*{}", var_name);
                if is_return {
                    dereference
                } else {
                    format!("std::move({})", dereference)
                }
            }
        })
    }
}
<commit_msg>Cease to use std::move if no conversion needed.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::conversion::{
    analysis::fun::function_wrapper::{CppConversionType, TypeConversionPolicy},
    ConvertError,
};

use super::type_to_cpp::{type_to_cpp, CppNameMap};

impl TypeConversionPolicy {
    pub(super) fn unconverted_type(
        &self,
        cpp_name_map: &CppNameMap,
    ) -> Result<String, ConvertError> {
        match self.cpp_conversion {
            CppConversionType::FromUniquePtrToValue => self.unique_ptr_wrapped_type(cpp_name_map),
            CppConversionType::FromPtrToValue => {
                Ok(format!("{}*", self.unwrapped_type_as_string(cpp_name_map)?))
            }
            _ => self.unwrapped_type_as_string(cpp_name_map),
        }
    }

    pub(super) fn converted_type(&self, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
        match self.cpp_conversion {
            CppConversionType::FromValueToUniquePtr => self.unique_ptr_wrapped_type(cpp_name_map),
            _ => self.unwrapped_type_as_string(cpp_name_map),
        }
    }

    fn unwrapped_type_as_string(&self, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
        type_to_cpp(&self.unwrapped_type, cpp_name_map)
    }

    fn unique_ptr_wrapped_type(
        &self,
        original_name_map: &CppNameMap,
    ) -> Result<String, ConvertError> {
        Ok(format!(
            "std::unique_ptr<{}>",
            self.unwrapped_type_as_string(original_name_map)?
        ))
    }

    pub(super) fn cpp_conversion(
        &self,
        var_name: &str,
        cpp_name_map: &CppNameMap,
        is_return: bool,
    ) -> Result<String, ConvertError> {
        // If is_return we want to avoid unnecessary std::moves because they
        // make RVO less effective
        Ok(match self.cpp_conversion {
            CppConversionType::None => {
                var_name.to_string()
            }
            CppConversionType::FromUniquePtrToValue | CppConversionType::FromPtrToMove => {
                format!("std::move(*{})", var_name)
            }
            CppConversionType::FromValueToUniquePtr => format!(
                "std::make_unique<{}>({})",
                self.unconverted_type(cpp_name_map)?,
                var_name
            ),
            CppConversionType::FromPtrToValue => {
                let dereference = format!("*{}", var_name);
                if is_return {
                    dereference
                } else {
                    format!("std::move({})", dereference)
                }
            }
        })
    }
}
<|endoftext|>


<commit_before>use std::mem;

use std::sync::Arc;

use select_query::{Queryable, Select, SelectOnly, SelectAll, LimitMany, NoResult};
use from::{From, Table, RcTable, RcFrom};
use predicate::{RcPredicate};
use expression::{Expression, UntypedExpression};

use expression::{
    RawExpr,
    ToExprValue,
    ExprValue,
    DefaultValue,
    ToExpression,
};

use sql::{ToSql, ToPredicateValue};
use field::{
    NamedField,
};

pub trait FieldUpd: ToSql {
    fn upcast_field_update(&self) -> RcFieldUpdate;
}

#[deriving(Send, Sync, Clone)]
pub struct FieldUpdate<F, T> {
    pub field: F,
    pub value: ExprValue<T>
}

impl<F, T> FieldUpdate<F, T> {
    pub fn get_field(&self) -> &F {
        &self.field
    }

    pub fn get_value(&self) -> &ExprValue<T> {
        &self.value
    }
}

pub type BoxedFieldUpdate = Box<FieldUpd + Send + Sync>;
pub type RcFieldUpdate = Arc<BoxedFieldUpdate>;

impl<F: Clone + Send + Sync + ToPredicateValue, T: Clone + Send + Sync + ToPredicateValue> FieldUpd for FieldUpdate<F, T> {
    fn upcast_field_update(&self) -> RcFieldUpdate {
        Arc::new(box self.clone() as BoxedFieldUpdate)
    }
}

pub trait ToFieldUpdate<F, T> {
    fn set<B: ToExpression<T>>(&self, val: &B) -> FieldUpdate<F, T>;
    fn set_default(&self) -> FieldUpdate<F, T>;
}

impl<T> ToFieldUpdate<NamedField<T>, T> for NamedField<T> where T: Clone {
    fn set<B: ToExpression<T>>(&self, val: &B) -> FieldUpdate<NamedField<T>, T> {
        FieldUpdate {
            field: self.clone(),
            value: val.as_expr().to_expr_val()
        }
    }

    fn set_default(&self) -> FieldUpdate<NamedField<T>, T> {
        FieldUpdate {
            field: self.clone(),
            value: DefaultValue
        }
    }
}

impl ToFieldUpdate<RawExpr, RawExpr> for RawExpr {
    fn set<B: ToExpression<RawExpr>>(&self, val: &B) -> FieldUpdate<RawExpr, RawExpr> {
        FieldUpdate {
            field: self.clone(),
            value: val.as_expr().to_expr_val()
        }
    }

    fn set_default(&self) -> FieldUpdate<RawExpr, RawExpr> {
        FieldUpdate {
            field: self.clone(),
            value: DefaultValue
        }
    }
}

// impl_for!(RawExpr, RawExpr)

pub trait Updatable<M>: Table {
    fn update(&self) -> UpdateQuery<(), NoResult, M> {
        UpdateQuery::new(self)
    }
}

#[deriving(Clone)]
pub struct UpdateQuery<T, L, M> {
    pub only: bool,
    pub table: RcTable,
    pub updates: Vec<RcFieldUpdate>,
    pub from: Option<Vec<RcFrom>>,
    pub where_: Option<RcPredicate>,
    pub all: bool,
    pub returning: Option<Select>
}

impl<T, L, M> UpdateQuery<T, L, M> {
    pub fn new(table: &Table) -> UpdateQuery<T, L, M> {
        UpdateQuery {
            only: false,
            table: table.upcast_table(),
            updates: vec![],
            from: None,
            where_: None,
            all: false,
            returning: None
        }
    }

    pub fn only(mut self) -> UpdateQuery<T, L, M> {
        self.only = true;
        self
    }

    pub fn from(mut self, from: &From) -> UpdateQuery<T, L, M> {
        if self.from.is_none() {
            self.from = Some(vec![])
        }

        self.from.as_mut().unwrap().push(from.upcast_from());
        self
    }

    pub fn field<F: FieldUpd>(mut self, update: F) -> UpdateQuery<T, L, M> {
        self.updates.push(update.upcast_field_update());
        self
    }

    pub fn all(mut self) -> UpdateQuery<T, L, M> {
        self.where_ = None;
        self.all = true;
        self
    }
}

returning_for!(UpdateQuery)

impl<T:Clone, L:Clone, M:Clone> Queryable for UpdateQuery<T, L, M> {
    fn get_where(&self) -> &Option<RcPredicate> { &self.where_ }
    fn set_where(&mut self, predicate: RcPredicate) { self.where_ = Some(predicate); }
    fn unset_where(&mut self) { self.where_ = None; }
}
<commit_msg>refactor: remove one more unused line<commit_after>use std::mem;

use std::sync::Arc;

use select_query::{Queryable, Select, SelectOnly, SelectAll, LimitMany, NoResult};
use from::{From, Table, RcTable, RcFrom};
use predicate::{RcPredicate};
use expression::{Expression, UntypedExpression};

use expression::{
    RawExpr,
    ToExprValue,
    ExprValue,
    DefaultValue,
    ToExpression,
};

use sql::{ToSql, ToPredicateValue};
use field::{
    NamedField,
};

pub trait FieldUpd: ToSql {
    fn upcast_field_update(&self) -> RcFieldUpdate;
}

#[deriving(Send, Sync, Clone)]
pub struct FieldUpdate<F, T> {
    pub field: F,
    pub value: ExprValue<T>
}

impl<F, T> FieldUpdate<F, T> {
    pub fn get_field(&self) -> &F {
        &self.field
    }

    pub fn get_value(&self) -> &ExprValue<T> {
        &self.value
    }
}

pub type BoxedFieldUpdate = Box<FieldUpd + Send + Sync>;
pub type RcFieldUpdate = Arc<BoxedFieldUpdate>;

impl<F: Clone + Send + Sync + ToPredicateValue, T: Clone + Send + Sync + ToPredicateValue> FieldUpd for FieldUpdate<F, T> {
    fn upcast_field_update(&self) -> RcFieldUpdate {
        Arc::new(box self.clone() as BoxedFieldUpdate)
    }
}

pub trait ToFieldUpdate<F, T> {
    fn set<B: ToExpression<T>>(&self, val: &B) -> FieldUpdate<F, T>;
    fn set_default(&self) -> FieldUpdate<F, T>;
}

impl<T> ToFieldUpdate<NamedField<T>, T> for NamedField<T> where T: Clone {
    fn set<B: ToExpression<T>>(&self, val: &B) -> FieldUpdate<NamedField<T>, T> {
        FieldUpdate {
            field: self.clone(),
            value: val.as_expr().to_expr_val()
        }
    }

    fn set_default(&self) -> FieldUpdate<NamedField<T>, T> {
        FieldUpdate {
            field: self.clone(),
            value: DefaultValue
        }
    }
}

impl ToFieldUpdate<RawExpr, RawExpr> for RawExpr {
    fn set<B: ToExpression<RawExpr>>(&self, val: &B) -> FieldUpdate<RawExpr, RawExpr> {
        FieldUpdate {
            field: self.clone(),
            value: val.as_expr().to_expr_val()
        }
    }

    fn set_default(&self) -> FieldUpdate<RawExpr, RawExpr> {
        FieldUpdate {
            field: self.clone(),
            value: DefaultValue
        }
    }
}

pub trait Updatable<M>: Table {
    fn update(&self) -> UpdateQuery<(), NoResult, M> {
        UpdateQuery::new(self)
    }
}

#[deriving(Clone)]
pub struct UpdateQuery<T, L, M> {
    pub only: bool,
    pub table: RcTable,
    pub updates: Vec<RcFieldUpdate>,
    pub from: Option<Vec<RcFrom>>,
    pub where_: Option<RcPredicate>,
    pub all: bool,
    pub returning: Option<Select>
}

impl<T, L, M> UpdateQuery<T, L, M> {
    pub fn new(table: &Table) -> UpdateQuery<T, L, M> {
        UpdateQuery {
            only: false,
            table: table.upcast_table(),
            updates: vec![],
            from: None,
            where_: None,
            all: false,
            returning: None
        }
    }

    pub fn only(mut self) -> UpdateQuery<T, L, M> {
        self.only = true;
        self
    }

    pub fn from(mut self, from: &From) -> UpdateQuery<T, L, M> {
        if self.from.is_none() {
            self.from = Some(vec![])
        }

        self.from.as_mut().unwrap().push(from.upcast_from());
        self
    }

    pub fn field<F: FieldUpd>(mut self, update: F) -> UpdateQuery<T, L, M> {
        self.updates.push(update.upcast_field_update());
        self
    }

    pub fn all(mut self) -> UpdateQuery<T, L, M> {
        self.where_ = None;
        self.all = true;
        self
    }
}

returning_for!(UpdateQuery)

impl<T:Clone, L:Clone, M:Clone> Queryable for UpdateQuery<T, L, M> {
    fn get_where(&self) -> &Option<RcPredicate> { &self.where_ }
    fn set_where(&mut self, predicate: RcPredicate) { self.where_ = Some(predicate); }
    fn unset_where(&mut self) { self.where_ = None; }
}
<|endoftext|>


<commit_before>extern crate num;
extern crate nalgebra as na;
use self::num::{Float, FromPrimitive};
use super::*;

/// Anything that implements this trait permits its space to be infinitely wrapping.
pub trait Toroid<V> {
    /// Wrap a delta vector between two positions inside of the toroidal space
    fn wrap_delta(&self, delta: V) -> V;

    /// Wrap a position to keep it inside of the space
    fn wrap_position(&self, pos: V) -> V;
}

pub trait Ball<D> {
    fn radius(&self) -> D;

    fn space<V>(&self) -> D
        where V: Vector<D>, D: Float
    {
        V::space_ball(self.radius())
    }
}

/// A Box with a center at origin and one of the corners created by offset
///
/// The box is aligned so that the face normals point along each axis.
pub struct Box<V> {
    pub origin: V,
    pub offset: V,
}

impl<V> Box<V> {
    pub fn new(origin: V, offset: V) -> Self {
        Box{
            origin: origin,
            offset: offset,
        }
    }

    //Compute the amount of space contained in the box
    pub fn space<D>(&self) -> D
        where V: Vector<D>, D: Float
    {
        self.offset.space_box()
    }
}

impl<D> Toroid<Cartesian1<D>> for Box<Cartesian1<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: Cartesian1<D>) -> Cartesian1<D> {
        Cartesian1{
            x: delta.x % (D::from_u32(2u32).unwrap() * self.offset.x),
        }
    }

    fn wrap_position(&self, pos: Cartesian1<D>) -> Cartesian1<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<Cartesian2<D>> for Box<Cartesian2<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: Cartesian2<D>) -> Cartesian2<D> {
        Cartesian2{
            x: delta.x % (D::from_u32(2u32).unwrap() * self.offset.x),
            y: delta.y % (D::from_u32(2u32).unwrap() * self.offset.y),
        }
    }

    fn wrap_position(&self, pos: Cartesian2<D>) -> Cartesian2<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<Cartesian3<D>> for Box<Cartesian3<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: Cartesian3<D>) -> Cartesian3<D> {
        Cartesian3{
            x: delta.x % (D::from_u32(2u32).unwrap() * self.offset.x),
            y: delta.y % (D::from_u32(2u32).unwrap() * self.offset.y),
            z: delta.z % (D::from_u32(2u32).unwrap() * self.offset.z),
        }
    }

    fn wrap_position(&self, pos: Cartesian3<D>) -> Cartesian3<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<na::Vec1<D>> for Box<na::Vec1<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: na::Vec1<D>) -> na::Vec1<D> {
        na::Vec1{
            x: delta.x % (D::from_u32(2u32).unwrap() * self.offset.x),
        }
    }

    fn wrap_position(&self, pos: na::Vec1<D>) -> na::Vec1<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<na::Vec2<D>> for Box<na::Vec2<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: na::Vec2<D>) -> na::Vec2<D> {
        na::Vec2{
            x: delta.x % (D::from_u32(2u32).unwrap() * self.offset.x),
            y: delta.y % (D::from_u32(2u32).unwrap() * self.offset.y),
        }
    }

    fn wrap_position(&self, pos: na::Vec2<D>) -> na::Vec2<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<na::Vec3<D>> for Box<na::Vec3<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: na::Vec3<D>) -> na::Vec3<D> {
        na::Vec3{
            x: delta.x % (D::from_u32(2u32).unwrap() * self.offset.x),
            y: delta.y % (D::from_u32(2u32).unwrap() * self.offset.y),
            z: delta.z % (D::from_u32(2u32).unwrap() * self.offset.z),
        }
    }

    fn wrap_position(&self, pos: na::Vec3<D>) -> na::Vec3<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<V> Clone for Box<V>
    where V: Clone
{
    fn clone(&self) -> Self {
        Box{
            origin: self.origin.clone(),
            offset: self.offset.clone(),
        }
    }
}
<commit_msg>fix bounding to make it work properly<commit_after>extern crate num;
extern crate nalgebra as na;
use self::num::{Float, FromPrimitive};
use super::*;

/// Anything that implements this trait permits its space to be infinitely wrapping.
pub trait Toroid<V> {
    /// Wrap a delta vector between two positions inside of the toroidal space
    fn wrap_delta(&self, delta: V) -> V;

    /// Wrap a position to keep it inside of the space
    fn wrap_position(&self, pos: V) -> V;
}

pub trait Ball<D> {
    fn radius(&self) -> D;

    fn space<V>(&self) -> D
        where V: Vector<D>, D: Float
    {
        V::space_ball(self.radius())
    }
}

/// A Box with a center at origin and one of the corners created by offset
///
/// The box is aligned so that the face normals point along each axis.
pub struct Box<V> {
    pub origin: V,
    pub offset: V,
}

impl<V> Box<V> {
    pub fn new(origin: V, offset: V) -> Self {
        Box{
            origin: origin,
            offset: offset,
        }
    }

    //Compute the amount of space contained in the box
    pub fn space<D>(&self) -> D
        where V: Vector<D>, D: Float
    {
        self.offset.space_box()
    }
}

fn wrap_scalar<D>(pos: D, bound: D) -> D where D: Float + FromPrimitive {
    // Bound must be positive
    let bound = bound.abs();
    let twobound = D::from_u32(2u32).unwrap() * bound;
    // Create shrunk_pos, which may still not be inside the space, but is within one stride of it
    let shrunk_pos = pos % twobound;

    if shrunk_pos < -bound {
        shrunk_pos + twobound
    } else if shrunk_pos > bound {
        shrunk_pos - twobound
    } else {
        shrunk_pos
    }
}

impl<D> Toroid<Cartesian1<D>> for Box<Cartesian1<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: Cartesian1<D>) -> Cartesian1<D> {
        Cartesian1{
            x: wrap_scalar(delta.x, self.offset.x),
        }
    }

    fn wrap_position(&self, pos: Cartesian1<D>) -> Cartesian1<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<Cartesian2<D>> for Box<Cartesian2<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: Cartesian2<D>) -> Cartesian2<D> {
        Cartesian2{
            x: wrap_scalar(delta.x, self.offset.x),
            y: wrap_scalar(delta.y, self.offset.y),
        }
    }

    fn wrap_position(&self, pos: Cartesian2<D>) -> Cartesian2<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<Cartesian3<D>> for Box<Cartesian3<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: Cartesian3<D>) -> Cartesian3<D> {
        Cartesian3{
            x: wrap_scalar(delta.x, self.offset.x),
            y: wrap_scalar(delta.y, self.offset.y),
            z: wrap_scalar(delta.z, self.offset.z),
        }
    }

    fn wrap_position(&self, pos: Cartesian3<D>) -> Cartesian3<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<na::Vec1<D>> for Box<na::Vec1<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: na::Vec1<D>) -> na::Vec1<D> {
        na::Vec1{
            x: wrap_scalar(delta.x, self.offset.x),
        }
    }

    fn wrap_position(&self, pos: na::Vec1<D>) -> na::Vec1<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<na::Vec2<D>> for Box<na::Vec2<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: na::Vec2<D>) -> na::Vec2<D> {
        na::Vec2{
            x: wrap_scalar(delta.x, self.offset.x),
            y: wrap_scalar(delta.y, self.offset.y),
        }
    }

    fn wrap_position(&self, pos: na::Vec2<D>) -> na::Vec2<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<D> Toroid<na::Vec3<D>> for Box<na::Vec3<D>>
    where D: Float + FromPrimitive
{
    fn wrap_delta(&self, delta: na::Vec3<D>) -> na::Vec3<D> {
        na::Vec3{
            x: wrap_scalar(delta.x, self.offset.x),
            y: wrap_scalar(delta.y, self.offset.y),
            z: wrap_scalar(delta.z, self.offset.z),
        }
    }

    fn wrap_position(&self, pos: na::Vec3<D>) -> na::Vec3<D> {
        self.wrap_delta(pos - self.origin) + self.origin
    }
}

impl<V> Clone for Box<V>
    where V: Clone
{
    fn clone(&self) -> Self {
        Box{
            origin: self.origin.clone(),
            offset: self.offset.clone(),
        }
    }
}
<|endoftext|>