<commit_before>//!
//! The Waveform trait along with various Waveform Types and there implementations.
//!

/// Some type that can return an amplitude given some phase.
pub trait Waveform {
    /// Return the amplitude given some phase.
    fn amp_at_phase(&self, phase: f64) -> f32;
    /// An optional method for processing the frequency.
    #[inline]
    fn process_hz(&self, hz: f64) -> f64 { hz }
}

/// Twice PI.
const PI_2: f64 = ::std::f64::consts::PI * 2.0;

/// Represents the "steepness" of the exponential saw wave.
pub type Steepness = f32;

/// An Oscillator must use one of a variety
/// of waveform types.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Dynamic {
    /// Sine Wave
    Sine,
    /// Saw Wave
    Saw,
    /// Square Wave
    Square,
    /// Noise
    Noise,
    /// Noise Walk
    NoiseWalk,
    /// Exponential Saw Wave.
    SawExp(Steepness),
}

/// A sine wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Sine;

/// A sawtooth wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Saw;

/// An exponential sawtooth wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SawExp(pub Steepness);

/// A square wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Square;

/// A noise signal.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Noise;

/// A random noise walk wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct NoiseWalk;

impl Waveform for Dynamic {
    /// Return the amplitude of a waveform at a given phase.
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        match *self {
            Dynamic::Sine => Sine.amp_at_phase(phase),
            Dynamic::Saw => Saw.amp_at_phase(phase),
            Dynamic::Square => Square.amp_at_phase(phase),
            Dynamic::Noise => Noise.amp_at_phase(phase),
            Dynamic::NoiseWalk => NoiseWalk.amp_at_phase(phase),
            Dynamic::SawExp(steepness) => SawExp(steepness).amp_at_phase(phase),
        }
    }
}

impl Waveform for Sine {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        (PI_2 * phase).sin() as f32
    }
}

impl Waveform for Saw {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        (::utils::fmod(phase, 1.0) * -2.0 + 1.0) as f32
    }
}

impl Waveform for SawExp {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        let SawExp(steepness) = *self;
        let saw = Saw.amp_at_phase(phase);
        saw * saw.abs().powf(steepness)
    }
}

impl Waveform for Square {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        (if ::utils::fmod(phase, 1.0) < 0.5 { -1.0 } else { 1.0 }) as f32
        //(if (PI_2 * phase).sin() < 0.0 { -1.0 } else { 1.0 }) as f32
    }
}

impl Waveform for Noise {
    #[inline]
    fn amp_at_phase(&self, _phase: f64) -> f32 {
        ::rand::random::<f32>() * 2.0 - 1.0
    }
}

impl Waveform for NoiseWalk {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        ::utils::noise_walk(phase as f32)
    }
    #[inline]
    fn process_hz(&self, hz: f64) -> f64 {
        use pitch;
        let perc = pitch::Hz(hz as f32).perc();
        pitch::ScaledPerc(perc, 0.6).hz() as f64
    }
}

<commit_msg>Remove dead code.<commit_after>//!
//! The Waveform trait along with various Waveform Types and there implementations.
//!

/// Some type that can return an amplitude given some phase.
pub trait Waveform {
    /// Return the amplitude given some phase.
    fn amp_at_phase(&self, phase: f64) -> f32;
    /// An optional method for processing the frequency.
    #[inline]
    fn process_hz(&self, hz: f64) -> f64 { hz }
}

/// Twice PI.
const PI_2: f64 = ::std::f64::consts::PI * 2.0;

/// Represents the "steepness" of the exponential saw wave.
pub type Steepness = f32;

/// An Oscillator must use one of a variety
/// of waveform types.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Dynamic {
    /// Sine Wave
    Sine,
    /// Saw Wave
    Saw,
    /// Square Wave
    Square,
    /// Noise
    Noise,
    /// Noise Walk
    NoiseWalk,
    /// Exponential Saw Wave.
    SawExp(Steepness),
}

/// A sine wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Sine;

/// A sawtooth wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Saw;

/// An exponential sawtooth wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SawExp(pub Steepness);

/// A square wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Square;

/// A noise signal.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Noise;

/// A random noise walk wave.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct NoiseWalk;

impl Waveform for Dynamic {
    /// Return the amplitude of a waveform at a given phase.
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        match *self {
            Dynamic::Sine => Sine.amp_at_phase(phase),
            Dynamic::Saw => Saw.amp_at_phase(phase),
            Dynamic::Square => Square.amp_at_phase(phase),
            Dynamic::Noise => Noise.amp_at_phase(phase),
            Dynamic::NoiseWalk => NoiseWalk.amp_at_phase(phase),
            Dynamic::SawExp(steepness) => SawExp(steepness).amp_at_phase(phase),
        }
    }
}

impl Waveform for Sine {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        (PI_2 * phase).sin() as f32
    }
}

impl Waveform for Saw {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        (::utils::fmod(phase, 1.0) * -2.0 + 1.0) as f32
    }
}

impl Waveform for SawExp {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        let SawExp(steepness) = *self;
        let saw = Saw.amp_at_phase(phase);
        saw * saw.abs().powf(steepness)
    }
}

impl Waveform for Square {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        (if ::utils::fmod(phase, 1.0) < 0.5 { -1.0 } else { 1.0 }) as f32
    }
}

impl Waveform for Noise {
    #[inline]
    fn amp_at_phase(&self, _phase: f64) -> f32 {
        ::rand::random::<f32>() * 2.0 - 1.0
    }
}

impl Waveform for NoiseWalk {
    #[inline]
    fn amp_at_phase(&self, phase: f64) -> f32 {
        ::utils::noise_walk(phase as f32)
    }
    #[inline]
    fn process_hz(&self, hz: f64) -> f64 {
        use pitch;
        let perc = pitch::Hz(hz as f32).perc();
        pitch::ScaledPerc(perc, 0.6).hz() as f64
    }
}

<|endoftext|>


<commit_before>//! [POST /_matrix/client/r0/user_directory/search](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-user-directory-search)

use js_int::{uint, UInt};
use ruma_api::ruma_api;
use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

ruma_api! {
    metadata: {
        description: "Performs a search for users.",
        method: POST,
        name: "search_users",
        path: "/_matrix/client/r0/user_directory/search",
        rate_limited: true,
        requires_authentication: true,
    }

    request: {
        /// The term to search for.
        pub search_term: &'a str,

        /// The maximum number of results to return.
        ///
        /// Defaults to 10.
        #[serde(default = "default_limit", skip_serializing_if = "is_default_limit")]
        pub limit: UInt,
    }

    response: {
        /// Ordered by rank and then whether or not profile info is available.
        pub results: Vec<User>,

        /// Indicates if the result list has been truncated by the limit.
        pub limited: bool,
    }

    error: crate::Error
}

fn default_limit() -> UInt {
    uint!(10)
}

fn is_default_limit(limit: &UInt) -> bool {
    limit == &default_limit()
}

/// User data as result of a search.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct User {
    /// The user's matrix user ID.
    pub user_id: UserId,

    /// The display name of the user, if one exists.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub display_name: Option<String>,

    /// The avatar url, as an MXC, if one exists.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,
}
<commit_msg>client-api: Add language field to search_users request<commit_after>//! [POST /_matrix/client/r0/user_directory/search](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-user-directory-search)

use js_int::{uint, UInt};
use ruma_api::ruma_api;
use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

ruma_api! {
    metadata: {
        description: "Performs a search for users.",
        method: POST,
        name: "search_users",
        path: "/_matrix/client/r0/user_directory/search",
        rate_limited: true,
        requires_authentication: true,
    }

    request: {
        /// The term to search for.
        pub search_term: &'a str,

        /// The maximum number of results to return.
        ///
        /// Defaults to 10.
        #[serde(default = "default_limit", skip_serializing_if = "is_default_limit")]
        pub limit: UInt,

        /// Language tag to determine the collation to use for the (case-insensitive) search.
        ///
        /// See [MDN] for the syntax.
        ///
        /// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language#Syntax
        #[ruma_api(header = ACCEPT_LANGUAGE)]
        pub language: Option<String>,
    }

    response: {
        /// Ordered by rank and then whether or not profile info is available.
        pub results: Vec<User>,

        /// Indicates if the result list has been truncated by the limit.
        pub limited: bool,
    }

    error: crate::Error
}

fn default_limit() -> UInt {
    uint!(10)
}

fn is_default_limit(limit: &UInt) -> bool {
    limit == &default_limit()
}

/// User data as result of a search.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct User {
    /// The user's matrix user ID.
    pub user_id: UserId,

    /// The display name of the user, if one exists.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub display_name: Option<String>,

    /// The avatar url, as an MXC, if one exists.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,
}
<|endoftext|>


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

use core::fmt;
use crate::parser;

impl From<parser::ParseError> for ::Error {
    fn from(err: parser::ParseError) -> Self {
        ::Error::Parse(err)
    }
}

impl<'a> fmt::Display for parser::Expected {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            parser::Expected::Any(ref crits) => write!(f, "one of {:?}", crits),
            parser::Expected::Exact(crit) => write!(f, "{}", crit),
            parser::Expected::Range { min, max } => {
                write!(f, "{}..{} inclusive", min, max)
            }
        }
    }
}

impl fmt::Display for parser::ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}: ", self._description())?;

        match *self {
            parser::ParseError::InvalidCharacter {
                expected,
                found,
                index,
            } => {
                write!(f, "expected {}, found {} at {}", expected, found, index)
            }
            parser::ParseError::InvalidGroupCount {
                ref expected,
                found,
            } => write!(f, "expected {}, found {}", expected, found),
            parser::ParseError::InvalidGroupLength {
                ref expected,
                found,
                group,
            } => write!(
                f,
                "expected {}, found {} in group {}",
                expected, found, group,
            ),
            parser::ParseError::InvalidLength {
                ref expected,
                found,
            } => write!(f, "expected {}, found {}", expected, found),
        }
    }
}
<commit_msg>fix the build<commit_after>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::fmt;
use crate::parser;

impl From<parser::ParseError> for crate::Error {
    fn from(err: parser::ParseError) -> Self {
        crate::Error::Parse(err)
    }
}

impl<'a> fmt::Display for parser::Expected {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            parser::Expected::Any(ref crits) => write!(f, "one of {:?}", crits),
            parser::Expected::Exact(crit) => write!(f, "{}", crit),
            parser::Expected::Range { min, max } => {
                write!(f, "{}..{} inclusive", min, max)
            }
        }
    }
}

impl fmt::Display for parser::ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}: ", self._description())?;

        match *self {
            parser::ParseError::InvalidCharacter {
                expected,
                found,
                index,
            } => {
                write!(f, "expected {}, found {} at {}", expected, found, index)
            }
            parser::ParseError::InvalidGroupCount {
                ref expected,
                found,
            } => write!(f, "expected {}, found {}", expected, found),
            parser::ParseError::InvalidGroupLength {
                ref expected,
                found,
                group,
            } => write!(
                f,
                "expected {}, found {} in group {}",
                expected, found, group,
            ),
            parser::ParseError::InvalidLength {
                ref expected,
                found,
            } => write!(f, "expected {}, found {}", expected, found),
        }
    }
}
<|endoftext|>


<commit_before>use super::*;

use crate::ffi::OsStr;
use crate::mem;
use crate::ptr;
use crate::sys::cvt;

macro_rules! t {
    ($e:expr) => {
        match $e {
            Ok(t) => t,
            Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
        }
    };
}

// See #14232 for more information, but it appears that signal delivery to a
// newly spawned process may just be raced in the macOS, so to prevent this
// test from being flaky we ignore it on macOS.
#[test]
#[cfg_attr(target_os = "macos", ignore)]
// When run under our current QEMU emulation test suite this test fails,
// although the reason isn't very clear as to why. For now this test is
// ignored there.
#[cfg_attr(target_arch = "arm", ignore)]
#[cfg_attr(target_arch = "aarch64", ignore)]
#[cfg_attr(target_arch = "riscv64", ignore)]
fn test_process_mask() {
    unsafe {
        // Test to make sure that a signal mask does not get inherited.
        let mut cmd = Command::new(OsStr::new("cat"));

        let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
        let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
        t!(cvt(sigemptyset(set.as_mut_ptr())));
        t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
        t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));

        cmd.stdin(Stdio::MakePipe);
        cmd.stdout(Stdio::MakePipe);

        let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
        let stdin_write = pipes.stdin.take().unwrap();
        let stdout_read = pipes.stdout.take().unwrap();

        t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut())));

        t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
        // We need to wait until SIGINT is definitely delivered. The
        // easiest way is to write something to cat, and try to read it
        // back: if SIGINT is unmasked, it'll get delivered when cat is
        // next scheduled.
        let _ = stdin_write.write(b"Hello");
        drop(stdin_write);

        // Either EOF or failure (EPIPE) is okay.
        let mut buf = [0; 5];
        if let Ok(ret) = stdout_read.read(&mut buf) {
            assert_eq!(ret, 0);
        }

        t!(cat.wait());
    }
}
<commit_msg>Rollup merge of #78878 - shepmaster:intersecting-ignores, r=Mark-Simulacrum<commit_after>use super::*;

use crate::ffi::OsStr;
use crate::mem;
use crate::ptr;
use crate::sys::cvt;

macro_rules! t {
    ($e:expr) => {
        match $e {
            Ok(t) => t,
            Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
        }
    };
}

#[test]
#[cfg_attr(
    any(
        // See #14232 for more information, but it appears that signal delivery to a
        // newly spawned process may just be raced in the macOS, so to prevent this
        // test from being flaky we ignore it on macOS.
        target_os = "macos",
        // When run under our current QEMU emulation test suite this test fails,
        // although the reason isn't very clear as to why. For now this test is
        // ignored there.
        target_arch = "arm",
        target_arch = "aarch64",
        target_arch = "riscv64",
    ),
    ignore
)]
fn test_process_mask() {
    unsafe {
        // Test to make sure that a signal mask does not get inherited.
        let mut cmd = Command::new(OsStr::new("cat"));

        let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
        let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
        t!(cvt(sigemptyset(set.as_mut_ptr())));
        t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
        t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));

        cmd.stdin(Stdio::MakePipe);
        cmd.stdout(Stdio::MakePipe);

        let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
        let stdin_write = pipes.stdin.take().unwrap();
        let stdout_read = pipes.stdout.take().unwrap();

        t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut())));

        t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
        // We need to wait until SIGINT is definitely delivered. The
        // easiest way is to write something to cat, and try to read it
        // back: if SIGINT is unmasked, it'll get delivered when cat is
        // next scheduled.
        let _ = stdin_write.write(b"Hello");
        drop(stdin_write);

        // Either EOF or failure (EPIPE) is okay.
        let mut buf = [0; 5];
        if let Ok(ret) = stdout_read.read(&mut buf) {
            assert_eq!(ret, 0);
        }

        t!(cat.wait());
    }
}
<|endoftext|>


<commit_before>use super::TermInfo;
use common::{BinarySerializable, VInt};
use common::{CompositeWrite, CountingWriter};
use core::Segment;
use directory::WritePtr;
use positions::PositionSerializer;
use postings::compression::{BlockEncoder, VIntEncoder, COMPRESSION_BLOCK_SIZE};
use postings::skip::SkipSerializer;
use postings::USE_SKIP_INFO_LIMIT;
use schema::Schema;
use schema::{Field, FieldEntry, FieldType};
use std::io::{self, Write};
use termdict::{TermDictionaryBuilder, TermOrdinal};
use DocId;
use Result;

/// `PostingsSerializer` is in charge of serializing
/// postings on disk, in the
/// * `.idx` (inverted index)
/// * `.pos` (positions file)
/// * `.term` (term dictionary)
///
/// `PostingsWriter` are in charge of pushing the data to the
/// serializer.
///
/// The serializer expects to receive the following calls
/// in this order :
/// * `set_field(...)`
/// * `new_term(...)`
/// * `write_doc(...)`
/// * `write_doc(...)`
/// * `write_doc(...)`
/// * ...
/// * `close_term()`
/// * `new_term(...)`
/// * `write_doc(...)`
/// * ...
/// * `close_term()`
/// * `set_field(...)`
/// * ...
/// * `close()`
///
/// Terms have to be pushed in a lexicographically-sorted order.
/// Within a term, document have to be pushed in increasing order.
///
/// A description of the serialization format is
/// [available here](https://fulmicoton.gitbooks.io/tantivy-doc/content/inverted-index.html).
pub struct InvertedIndexSerializer {
    terms_write: CompositeWrite<WritePtr>,
    postings_write: CompositeWrite<WritePtr>,
    positions_write: CompositeWrite<WritePtr>,
    positionsidx_write: CompositeWrite<WritePtr>,
    schema: Schema,
}

impl InvertedIndexSerializer {
    /// Open a new `PostingsSerializer` for the given segment
    fn create(
        terms_write: CompositeWrite<WritePtr>,
        postings_write: CompositeWrite<WritePtr>,
        positions_write: CompositeWrite<WritePtr>,
        positionsidx_write: CompositeWrite<WritePtr>,
        schema: Schema,
    ) -> Result<InvertedIndexSerializer> {
        Ok(InvertedIndexSerializer {
            terms_write,
            postings_write,
            positions_write,
            positionsidx_write,
            schema,
        })
    }

    /// Open a new `PostingsSerializer` for the given segment
    pub fn open(segment: &mut Segment) -> Result<InvertedIndexSerializer> {
        use SegmentComponent::{POSITIONS, POSITIONSSKIP, POSTINGS, TERMS};
        InvertedIndexSerializer::create(
            CompositeWrite::wrap(segment.open_write(TERMS)?),
            CompositeWrite::wrap(segment.open_write(POSTINGS)?),
            CompositeWrite::wrap(segment.open_write(POSITIONS)?),
            CompositeWrite::wrap(segment.open_write(POSITIONSSKIP)?),
            segment.schema(),
        )
    }

    /// Must be called before starting pushing terms of
    /// a given field.
    ///
    /// Loads the indexing options for the given field.
    pub fn new_field(
        &mut self,
        field: Field,
        total_num_tokens: u64,
    ) -> io::Result<FieldSerializer> {
        let field_entry: &FieldEntry = self.schema.get_field_entry(field);
        let term_dictionary_write = self.terms_write.for_field(field);
        let postings_write = self.postings_write.for_field(field);
        total_num_tokens.serialize(postings_write)?;
        let positions_write = self.positions_write.for_field(field);
        let positionsidx_write = self.positionsidx_write.for_field(field);
        let field_type: FieldType = (*field_entry.field_type()).clone();
        FieldSerializer::create(
            &field_type,
            term_dictionary_write,
            postings_write,
            positions_write,
            positionsidx_write,
        )
    }

    /// Closes the serializer.
    pub fn close(self) -> io::Result<()> {
        self.terms_write.close()?;
        self.postings_write.close()?;
        self.positions_write.close()?;
        self.positionsidx_write.close()?;
        Ok(())
    }
}

/// The field serializer is in charge of
/// the serialization of a specific field.
pub struct FieldSerializer<'a> {
    term_dictionary_builder: TermDictionaryBuilder<&'a mut CountingWriter<WritePtr>>,
    postings_serializer: PostingsSerializer<&'a mut CountingWriter<WritePtr>>,
    positions_serializer_opt: Option<PositionSerializer<&'a mut CountingWriter<WritePtr>>>,
    current_term_info: TermInfo,
    term_open: bool,
    num_terms: TermOrdinal,
}

impl<'a> FieldSerializer<'a> {
    fn create(
        field_type: &FieldType,
        term_dictionary_write: &'a mut CountingWriter<WritePtr>,
        postings_write: &'a mut CountingWriter<WritePtr>,
        positions_write: &'a mut CountingWriter<WritePtr>,
        positionsidx_write: &'a mut CountingWriter<WritePtr>,
    ) -> io::Result<FieldSerializer<'a>> {
        let (term_freq_enabled, position_enabled): (bool, bool) = match field_type {
            FieldType::Str(ref text_options) => {
                if let Some(text_indexing_options) = text_options.get_indexing_options() {
                    let index_option = text_indexing_options.index_option();
                    (
                        index_option.is_termfreq_enabled(),
                        index_option.is_position_enabled(),
                    )
                } else {
                    (false, false)
                }
            }
            _ => (false, false),
        };
        let term_dictionary_builder =
            TermDictionaryBuilder::create(term_dictionary_write, &field_type)?;
        let postings_serializer =
            PostingsSerializer::new(postings_write, term_freq_enabled, position_enabled);
        let positions_serializer_opt = if position_enabled {
            Some(PositionSerializer::new(positions_write, positionsidx_write))
        } else {
            None
        };

        Ok(FieldSerializer {
            term_dictionary_builder,
            postings_serializer,
            positions_serializer_opt,
            current_term_info: TermInfo::default(),
            term_open: false,
            num_terms: TermOrdinal::default(),
        })
    }

    fn current_term_info(&self) -> TermInfo {
        let positions_idx = self
            .positions_serializer_opt
            .as_ref()
            .map(|positions_serializer| positions_serializer.positions_idx())
            .unwrap_or(0u64);
        TermInfo {
            doc_freq: 0,
            postings_offset: self.postings_serializer.addr(),
            positions_idx,
        }
    }

    /// Starts the postings for a new term.
    /// * term - the term. It needs to come after the previous term according
    ///   to the lexicographical order.
    /// * doc_freq - return the number of document containing the term.
    pub fn new_term(&mut self, term: &[u8]) -> io::Result<TermOrdinal> {
        assert!(
            !self.term_open,
            "Called new_term, while the previous term was not closed."
        );
        self.term_open = true;
        self.postings_serializer.clear();
        self.current_term_info = self.current_term_info();
        self.term_dictionary_builder.insert_key(term)?;
        let term_ordinal = self.num_terms;
        self.num_terms += 1;
        Ok(term_ordinal)
    }

    /// Serialize the information that a document contains the current term,
    /// its term frequency, and the position deltas.
    ///
    /// At this point, the positions are already `delta-encoded`.
    /// For instance, if the positions are `2, 3, 17`,
    /// `position_deltas` is `2, 1, 14`
    ///
    /// Term frequencies and positions may be ignored by the serializer depending
    /// on the configuration of the field in the `Schema`.
    pub fn write_doc(
        &mut self,
        doc_id: DocId,
        term_freq: u32,
        position_deltas: &[u32],
    ) -> io::Result<()> {
        self.current_term_info.doc_freq += 1;
        self.postings_serializer.write_doc(doc_id, term_freq);
        if let Some(ref mut positions_serializer) = self.positions_serializer_opt.as_mut() {
            positions_serializer.write_all(position_deltas)?;
        }
        Ok(())
    }

    /// Finish the serialization for this term postings.
    ///
    /// If the current block is incomplete, it need to be encoded
    /// using `VInt` encoding.
    pub fn close_term(&mut self) -> io::Result<()> {
        if self.term_open {
            self.term_dictionary_builder
                .insert_value(&self.current_term_info)?;
            self.postings_serializer
                .close_term(self.current_term_info.doc_freq)?;
            self.term_open = false;
        }
        Ok(())
    }

    /// Closes the current current field.
    pub fn close(mut self) -> io::Result<()> {
        self.close_term()?;
        if let Some(positions_serializer) = self.positions_serializer_opt {
            positions_serializer.close()?;
        }
        self.postings_serializer.close()?;
        self.term_dictionary_builder.finish()?;
        Ok(())
    }
}

struct Block {
    doc_ids: [DocId; COMPRESSION_BLOCK_SIZE],
    term_freqs: [u32; COMPRESSION_BLOCK_SIZE],
    len: usize,
}

impl Block {
    fn new() -> Self {
        Block {
            doc_ids: [0u32; COMPRESSION_BLOCK_SIZE],
            term_freqs: [0u32; COMPRESSION_BLOCK_SIZE],
            len: 0,
        }
    }

    fn doc_ids(&self) -> &[DocId] {
        &self.doc_ids[..self.len]
    }

    fn term_freqs(&self) -> &[u32] {
        &self.term_freqs[..self.len]
    }

    fn clear(&mut self) {
        self.len = 0;
    }

    fn append_doc(&mut self, doc: DocId, term_freq: u32) {
        let len = self.len;
        self.doc_ids[len] = doc;
        self.term_freqs[len] = term_freq;
        self.len = len + 1;
    }

    fn is_full(&self) -> bool {
        self.len == COMPRESSION_BLOCK_SIZE
    }

    fn is_empty(&self) -> bool {
        self.len == 0
    }

    fn last_doc(&self) -> DocId {
        assert_eq!(self.len, COMPRESSION_BLOCK_SIZE);
        self.doc_ids[COMPRESSION_BLOCK_SIZE - 1]
    }
}

pub struct PostingsSerializer<W: Write> {
    output_write: CountingWriter<W>,
    last_doc_id_encoded: u32,

    block_encoder: BlockEncoder,
    block: Box<Block>,

    postings_write: Vec<u8>,
    skip_write: SkipSerializer,

    termfreq_enabled: bool,
    termfreq_sum_enabled: bool,
}

impl<W: Write> PostingsSerializer<W> {
    pub fn new(
        write: W,
        termfreq_enabled: bool,
        termfreq_sum_enabled: bool,
    ) -> PostingsSerializer<W> {
        PostingsSerializer {
            output_write: CountingWriter::wrap(write),

            block_encoder: BlockEncoder::new(),
            block: Box::new(Block::new()),

            postings_write: Vec::new(),
            skip_write: SkipSerializer::new(),

            last_doc_id_encoded: 0u32,
            termfreq_enabled,
            termfreq_sum_enabled,
        }
    }

    fn write_block(&mut self) {
        {
            // encode the doc ids
            let (num_bits, block_encoded): (u8, &[u8]) = self
                .block_encoder
                .compress_block_sorted(&self.block.doc_ids(), self.last_doc_id_encoded);
            self.last_doc_id_encoded = self.block.last_doc();
            self.skip_write
                .write_doc(self.last_doc_id_encoded, num_bits);
            // last el block 0, offset block 1,
            self.postings_write.extend(block_encoded);
        }
        if self.termfreq_enabled {
            // encode the term_freqs
            let (num_bits, block_encoded): (u8, &[u8]) = self
                .block_encoder
                .compress_block_unsorted(&self.block.term_freqs());
            self.postings_write.extend(block_encoded);
            self.skip_write.write_term_freq(num_bits);
            if self.termfreq_sum_enabled {
                let sum_freq = self.block.term_freqs().iter().cloned().sum();
                self.skip_write.write_total_term_freq(sum_freq);
            }
        }
        self.block.clear();
    }

    pub fn write_doc(&mut self, doc_id: DocId, term_freq: u32) {
        self.block.append_doc(doc_id, term_freq);
        if self.block.is_full() {
            self.write_block();
        }
    }

    fn close(mut self) -> io::Result<()> {
        self.postings_write.flush()
    }

    pub fn close_term(&mut self, doc_freq: u32) -> io::Result<()> {
        if !self.block.is_empty() {
            // we have doc ids waiting to be written
            // this happens when the number of doc ids is
            // not a perfect multiple of our block size.
            //
            // In that case, the remaining part is encoded
            // using variable int encoding.
            {
                let block_encoded = self
                    .block_encoder
                    .compress_vint_sorted(&self.block.doc_ids(), self.last_doc_id_encoded);
                self.postings_write.write_all(block_encoded)?;
            }
            // ... Idem for term frequencies
            if self.termfreq_enabled {
                let block_encoded = self
                    .block_encoder
                    .compress_vint_unsorted(self.block.term_freqs());
                self.postings_write.write_all(block_encoded)?;
            }
            self.block.clear();
        }
        if doc_freq >= USE_SKIP_INFO_LIMIT {
            let skip_data = self.skip_write.data();
            VInt(skip_data.len() as u64).serialize(&mut self.output_write)?;
            self.output_write.write_all(skip_data)?;
            self.output_write.write_all(&self.postings_write[..])?;
        } else {
            self.output_write.write_all(&self.postings_write[..])?;
        }
        self.skip_write.clear();
        self.postings_write.clear();
        Ok(())
    }

    fn addr(&self) -> u64 {
        self.output_write.written_bytes() as u64
    }

    fn clear(&mut self) {
        self.block.clear();
        self.last_doc_id_encoded = 0;
    }
}
<commit_msg>Fix comment<commit_after>use super::TermInfo;
use common::{BinarySerializable, VInt};
use common::{CompositeWrite, CountingWriter};
use core::Segment;
use directory::WritePtr;
use positions::PositionSerializer;
use postings::compression::{BlockEncoder, VIntEncoder, COMPRESSION_BLOCK_SIZE};
use postings::skip::SkipSerializer;
use postings::USE_SKIP_INFO_LIMIT;
use schema::Schema;
use schema::{Field, FieldEntry, FieldType};
use std::io::{self, Write};
use termdict::{TermDictionaryBuilder, TermOrdinal};
use DocId;
use Result;

/// `InvertedIndexSerializer` is in charge of serializing
/// postings on disk, in the
/// * `.idx` (inverted index)
/// * `.pos` (positions file)
/// * `.term` (term dictionary)
///
/// `PostingsWriter` are in charge of pushing the data to the
/// serializer.
///
/// The serializer expects to receive the following calls
/// in this order :
/// * `set_field(...)`
/// * `new_term(...)`
/// * `write_doc(...)`
/// * `write_doc(...)`
/// * `write_doc(...)`
/// * ...
/// * `close_term()`
/// * `new_term(...)`
/// * `write_doc(...)`
/// * ...
/// * `close_term()`
/// * `set_field(...)`
/// * ...
/// * `close()`
///
/// Terms have to be pushed in a lexicographically-sorted order.
/// Within a term, document have to be pushed in increasing order.
///
/// A description of the serialization format is
/// [available here](https://fulmicoton.gitbooks.io/tantivy-doc/content/inverted-index.html).
pub struct InvertedIndexSerializer {
    terms_write: CompositeWrite<WritePtr>,
    postings_write: CompositeWrite<WritePtr>,
    positions_write: CompositeWrite<WritePtr>,
    positionsidx_write: CompositeWrite<WritePtr>,
    schema: Schema,
}

impl InvertedIndexSerializer {
    /// Open a new `InvertedIndexSerializer` for the given segment
    fn create(
        terms_write: CompositeWrite<WritePtr>,
        postings_write: CompositeWrite<WritePtr>,
        positions_write: CompositeWrite<WritePtr>,
        positionsidx_write: CompositeWrite<WritePtr>,
        schema: Schema,
    ) -> Result<InvertedIndexSerializer> {
        Ok(InvertedIndexSerializer {
            terms_write,
            postings_write,
            positions_write,
            positionsidx_write,
            schema,
        })
    }

    /// Open a new `PostingsSerializer` for the given segment
    pub fn open(segment: &mut Segment) -> Result<InvertedIndexSerializer> {
        use SegmentComponent::{POSITIONS, POSITIONSSKIP, POSTINGS, TERMS};
        InvertedIndexSerializer::create(
            CompositeWrite::wrap(segment.open_write(TERMS)?),
            CompositeWrite::wrap(segment.open_write(POSTINGS)?),
            CompositeWrite::wrap(segment.open_write(POSITIONS)?),
            CompositeWrite::wrap(segment.open_write(POSITIONSSKIP)?),
            segment.schema(),
        )
    }

    /// Must be called before starting pushing terms of
    /// a given field.
    ///
    /// Loads the indexing options for the given field.
    pub fn new_field(
        &mut self,
        field: Field,
        total_num_tokens: u64,
    ) -> io::Result<FieldSerializer> {
        let field_entry: &FieldEntry = self.schema.get_field_entry(field);
        let term_dictionary_write = self.terms_write.for_field(field);
        let postings_write = self.postings_write.for_field(field);
        total_num_tokens.serialize(postings_write)?;
        let positions_write = self.positions_write.for_field(field);
        let positionsidx_write = self.positionsidx_write.for_field(field);
        let field_type: FieldType = (*field_entry.field_type()).clone();
        FieldSerializer::create(
            &field_type,
            term_dictionary_write,
            postings_write,
            positions_write,
            positionsidx_write,
        )
    }

    /// Closes the serializer.
    pub fn close(self) -> io::Result<()> {
        self.terms_write.close()?;
        self.postings_write.close()?;
        self.positions_write.close()?;
        self.positionsidx_write.close()?;
        Ok(())
    }
}

/// The field serializer is in charge of
/// the serialization of a specific field.
pub struct FieldSerializer<'a> {
    term_dictionary_builder: TermDictionaryBuilder<&'a mut CountingWriter<WritePtr>>,
    postings_serializer: PostingsSerializer<&'a mut CountingWriter<WritePtr>>,
    positions_serializer_opt: Option<PositionSerializer<&'a mut CountingWriter<WritePtr>>>,
    current_term_info: TermInfo,
    term_open: bool,
    num_terms: TermOrdinal,
}

impl<'a> FieldSerializer<'a> {
    fn create(
        field_type: &FieldType,
        term_dictionary_write: &'a mut CountingWriter<WritePtr>,
        postings_write: &'a mut CountingWriter<WritePtr>,
        positions_write: &'a mut CountingWriter<WritePtr>,
        positionsidx_write: &'a mut CountingWriter<WritePtr>,
    ) -> io::Result<FieldSerializer<'a>> {
        let (term_freq_enabled, position_enabled): (bool, bool) = match field_type {
            FieldType::Str(ref text_options) => {
                if let Some(text_indexing_options) = text_options.get_indexing_options() {
                    let index_option = text_indexing_options.index_option();
                    (
                        index_option.is_termfreq_enabled(),
                        index_option.is_position_enabled(),
                    )
                } else {
                    (false, false)
                }
            }
            _ => (false, false),
        };
        let term_dictionary_builder =
            TermDictionaryBuilder::create(term_dictionary_write, &field_type)?;
        let postings_serializer =
            PostingsSerializer::new(postings_write, term_freq_enabled, position_enabled);
        let positions_serializer_opt = if position_enabled {
            Some(PositionSerializer::new(positions_write, positionsidx_write))
        } else {
            None
        };

        Ok(FieldSerializer {
            term_dictionary_builder,
            postings_serializer,
            positions_serializer_opt,
            current_term_info: TermInfo::default(),
            term_open: false,
            num_terms: TermOrdinal::default(),
        })
    }

    fn current_term_info(&self) -> TermInfo {
        let positions_idx = self
            .positions_serializer_opt
            .as_ref()
            .map(|positions_serializer| positions_serializer.positions_idx())
            .unwrap_or(0u64);
        TermInfo {
            doc_freq: 0,
            postings_offset: self.postings_serializer.addr(),
            positions_idx,
        }
    }

    /// Starts the postings for a new term.
    /// * term - the term. It needs to come after the previous term according
    ///   to the lexicographical order.
    /// * doc_freq - return the number of document containing the term.
    pub fn new_term(&mut self, term: &[u8]) -> io::Result<TermOrdinal> {
        assert!(
            !self.term_open,
            "Called new_term, while the previous term was not closed."
        );
        self.term_open = true;
        self.postings_serializer.clear();
        self.current_term_info = self.current_term_info();
        self.term_dictionary_builder.insert_key(term)?;
        let term_ordinal = self.num_terms;
        self.num_terms += 1;
        Ok(term_ordinal)
    }

    /// Serialize the information that a document contains the current term,
    /// its term frequency, and the position deltas.
    ///
    /// At this point, the positions are already `delta-encoded`.
    /// For instance, if the positions are `2, 3, 17`,
    /// `position_deltas` is `2, 1, 14`
    ///
    /// Term frequencies and positions may be ignored by the serializer depending
    /// on the configuration of the field in the `Schema`.
    pub fn write_doc(
        &mut self,
        doc_id: DocId,
        term_freq: u32,
        position_deltas: &[u32],
    ) -> io::Result<()> {
        self.current_term_info.doc_freq += 1;
        self.postings_serializer.write_doc(doc_id, term_freq);
        if let Some(ref mut positions_serializer) = self.positions_serializer_opt.as_mut() {
            positions_serializer.write_all(position_deltas)?;
        }
        Ok(())
    }

    /// Finish the serialization for this term postings.
    ///
    /// If the current block is incomplete, it need to be encoded
    /// using `VInt` encoding.
    pub fn close_term(&mut self) -> io::Result<()> {
        if self.term_open {
            self.term_dictionary_builder
                .insert_value(&self.current_term_info)?;
            self.postings_serializer
                .close_term(self.current_term_info.doc_freq)?;
            self.term_open = false;
        }
        Ok(())
    }

    /// Closes the current current field.
    pub fn close(mut self) -> io::Result<()> {
        self.close_term()?;
        if let Some(positions_serializer) = self.positions_serializer_opt {
            positions_serializer.close()?;
        }
        self.postings_serializer.close()?;
        self.term_dictionary_builder.finish()?;
        Ok(())
    }
}

struct Block {
    doc_ids: [DocId; COMPRESSION_BLOCK_SIZE],
    term_freqs: [u32; COMPRESSION_BLOCK_SIZE],
    len: usize,
}

impl Block {
    fn new() -> Self {
        Block {
            doc_ids: [0u32; COMPRESSION_BLOCK_SIZE],
            term_freqs: [0u32; COMPRESSION_BLOCK_SIZE],
            len: 0,
        }
    }

    fn doc_ids(&self) -> &[DocId] {
        &self.doc_ids[..self.len]
    }

    fn term_freqs(&self) -> &[u32] {
        &self.term_freqs[..self.len]
    }

    fn clear(&mut self) {
        self.len = 0;
    }

    fn append_doc(&mut self, doc: DocId, term_freq: u32) {
        let len = self.len;
        self.doc_ids[len] = doc;
        self.term_freqs[len] = term_freq;
        self.len = len + 1;
    }

    fn is_full(&self) -> bool {
        self.len == COMPRESSION_BLOCK_SIZE
    }

    fn is_empty(&self) -> bool {
        self.len == 0
    }

    fn last_doc(&self) -> DocId {
        assert_eq!(self.len, COMPRESSION_BLOCK_SIZE);
        self.doc_ids[COMPRESSION_BLOCK_SIZE - 1]
    }
}

pub struct PostingsSerializer<W: Write> {
    output_write: CountingWriter<W>,
    last_doc_id_encoded: u32,

    block_encoder: BlockEncoder,
    block: Box<Block>,

    postings_write: Vec<u8>,
    skip_write: SkipSerializer,

    termfreq_enabled: bool,
    termfreq_sum_enabled: bool,
}

impl<W: Write> PostingsSerializer<W> {
    pub fn new(
        write: W,
        termfreq_enabled: bool,
        termfreq_sum_enabled: bool,
    ) -> PostingsSerializer<W> {
        PostingsSerializer {
            output_write: CountingWriter::wrap(write),

            block_encoder: BlockEncoder::new(),
            block: Box::new(Block::new()),

            postings_write: Vec::new(),
            skip_write: SkipSerializer::new(),

            last_doc_id_encoded: 0u32,
            termfreq_enabled,
            termfreq_sum_enabled,
        }
    }

    fn write_block(&mut self) {
        {
            // encode the doc ids
            let (num_bits, block_encoded): (u8, &[u8]) = self
                .block_encoder
                .compress_block_sorted(&self.block.doc_ids(), self.last_doc_id_encoded);
            self.last_doc_id_encoded = self.block.last_doc();
            self.skip_write
                .write_doc(self.last_doc_id_encoded, num_bits);
            // last el block 0, offset block 1,
            self.postings_write.extend(block_encoded);
        }
        if self.termfreq_enabled {
            // encode the term_freqs
            let (num_bits, block_encoded): (u8, &[u8]) = self
                .block_encoder
                .compress_block_unsorted(&self.block.term_freqs());
            self.postings_write.extend(block_encoded);
            self.skip_write.write_term_freq(num_bits);
            if self.termfreq_sum_enabled {
                let sum_freq = self.block.term_freqs().iter().cloned().sum();
                self.skip_write.write_total_term_freq(sum_freq);
            }
        }
        self.block.clear();
    }

    pub fn write_doc(&mut self, doc_id: DocId, term_freq: u32) {
        self.block.append_doc(doc_id, term_freq);
        if self.block.is_full() {
            self.write_block();
        }
    }

    fn close(mut self) -> io::Result<()> {
        self.postings_write.flush()
    }

    pub fn close_term(&mut self, doc_freq: u32) -> io::Result<()> {
        if !self.block.is_empty() {
            // we have doc ids waiting to be written
            // this happens when the number of doc ids is
            // not a perfect multiple of our block size.
            //
            // In that case, the remaining part is encoded
            // using variable int encoding.
            {
                let block_encoded = self
                    .block_encoder
                    .compress_vint_sorted(&self.block.doc_ids(), self.last_doc_id_encoded);
                self.postings_write.write_all(block_encoded)?;
            }
            // ... Idem for term frequencies
            if self.termfreq_enabled {
                let block_encoded = self
                    .block_encoder
                    .compress_vint_unsorted(self.block.term_freqs());
                self.postings_write.write_all(block_encoded)?;
            }
            self.block.clear();
        }
        if doc_freq >= USE_SKIP_INFO_LIMIT {
            let skip_data = self.skip_write.data();
            VInt(skip_data.len() as u64).serialize(&mut self.output_write)?;
            self.output_write.write_all(skip_data)?;
            self.output_write.write_all(&self.postings_write[..])?;
        } else {
            self.output_write.write_all(&self.postings_write[..])?;
        }
        self.skip_write.clear();
        self.postings_write.clear();
        Ok(())
    }

    fn addr(&self) -> u64 {
        self.output_write.written_bytes() as u64
    }

    fn clear(&mut self) {
        self.block.clear();
        self.last_doc_id_encoded = 0;
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
use std::ops::{Add, Mul, Sub};

macro_rules! assert_equal_len {
    // The `tt` (token tree) designator is used for
    // operators and tokens.
    ($a:ident, $b: ident, $func:ident, $op:tt) => (
        assert!($a.len() == $b.len(),
                "{:?}: dimension mismatch: {:?} {:?} {:?}",
                stringify!($func),
                ($a.len(),),
                stringify!($op),
                ($b.len(),));
    )
}

macro_rules! op {
    ($func:ident, $bound:ident, $op:tt, $method:ident) => (
        fn $func<T: $bound<T, Output=T> + Copy>(xs: &mut Vec<T>, ys: &Vec<T>) {
            assert_equal_len!(xs, ys, $func, $op);

            for (x, y) in xs.iter_mut().zip(ys.iter()) {
                *x = $bound::$method(*x, *y);
                // *x = x.$method(*y);
            }
        }
    )
}

pub fn main() {
    // Implement `add_assign`, `mul_assign`, and `sub_assign` functions.
    op!(add_assign, Add, +=, add);
    op!(mul_assign, Mul, *=, mul);
    op!(sub_assign, Sub, -=, sub);
}

mod test {
    //use std::iter;
    macro_rules! test {
        ($func: ident, $x:expr, $y:expr, $z:expr) => {
            #[test]
            fn $func() {
                for size in 0usize..10 {
                    let mut x: Vec<_> = iter::repeat($x).take(size).collect();
                    let y: Vec<_> = iter::repeat($y).take(size).collect();
                    let z: Vec<_> = iter::repeat($z).take(size).collect();

                    super::$func(&mut x, &y);

                    assert_eq!(x, z);
                }
            }
        }
    }

    // Test `add_assign`, `mul_assign` and `sub_assign`
    test!(add_assign, 1u32, 2u32, 3u32);
    test!(mul_assign, 2u32, 3u32, 6u32);
    test!(sub_assign, 3u32, 2u32, 1u32);
}
<commit_msg>Fix tests<commit_after>#![allow(dead_code)]
use std::ops::{Add, Mul, Sub};

macro_rules! assert_equal_len {
    // The `tt` (token tree) designator is used for
    // operators and tokens.
    ($a:ident, $b: ident, $func:ident, $op:tt) => (
        assert!($a.len() == $b.len(),
                "{:?}: dimension mismatch: {:?} {:?} {:?}",
                stringify!($func),
                ($a.len(),),
                stringify!($op),
                ($b.len(),));
    )
}

macro_rules! op {
    ($func:ident, $bound:ident, $op:tt, $method:ident) => (
        fn $func<T: $bound<T, Output=T> + Copy>(xs: &mut Vec<T>, ys: &Vec<T>) {
            assert_equal_len!(xs, ys, $func, $op);

            for (x, y) in xs.iter_mut().zip(ys.iter()) {
                *x = $bound::$method(*x, *y);
                // *x = x.$method(*y);
            }
        }
    )
}

pub fn main() {
    // Implement `add_assign`, `mul_assign`, and `sub_assign` functions.
    op!(add_assign, Add, +=, add);
    op!(mul_assign, Mul, *=, mul);
    op!(sub_assign, Sub, -=, sub);
}

mod test {
    //use std::iter;
    macro_rules! test {
        ($func: ident, $x:expr, $y:expr, $z:expr) => {
            #[test]
            fn $func() {
                for size in 0usize..10 {
                    let mut x: Vec<_> = iter::repeat($x).take(size).collect();
                    let y: Vec<_> = iter::repeat($y).take(size).collect();
                    let z: Vec<_> = iter::repeat($z).take(size).collect();

                    $func(&mut x, &y);

                    assert_eq!(x, z);
                }
            }
        }
    }

    // Test `add_assign`, `mul_assign` and `sub_assign`
    //test!(add_assign, 1u32, 2u32, 3u32);
    //test!(mul_assign, 2u32, 3u32, 6u32);
    //test!(sub_assign, 3u32, 2u32, 1u32);
}
<|endoftext|>


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

extern crate serde_bytes;

use font::{FontInstanceKey, FontKey, FontTemplate};
use std::sync::Arc;
use {DevicePoint, DeviceUintRect, IdNamespace, TileOffset, TileSize};

#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ImageKey(pub IdNamespace, pub u32);

impl ImageKey {
    pub const DUMMY: Self = ImageKey(IdNamespace(0), 0);

    pub fn new(namespace: IdNamespace, key: u32) -> Self {
        ImageKey(namespace, key)
    }
}

/// An arbitrary identifier for an external image provided by the
/// application. It must be a unique identifier for each external
/// image.
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ExternalImageId(pub u64);

#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum TextureTarget {
    Default = 0,
    Array = 1,
    Rect = 2,
    External = 3,
}

#[repr(u32)]
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum ExternalImageType {
    TextureHandle(TextureTarget),
    Buffer,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ExternalImageData {
    pub id: ExternalImageId,
    pub channel_index: u8,
    pub image_type: ExternalImageType,
}

#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ImageFormat {
    R8 = 1,
    BGRA8 = 3,
    RGBAF32 = 4,
    RG8 = 5,
}

impl ImageFormat {
    pub fn bytes_per_pixel(self) -> u32 {
        match self {
            ImageFormat::R8 => 1,
            ImageFormat::BGRA8 => 4,
            ImageFormat::RGBAF32 => 16,
            ImageFormat::RG8 => 2,
        }
    }
}

#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageDescriptor {
    pub format: ImageFormat,
    pub width: u32,
    pub height: u32,
    pub stride: Option<u32>,
    pub offset: u32,
    pub is_opaque: bool,
    pub allow_mipmaps: bool,
}

impl ImageDescriptor {
    pub fn new(
        width: u32,
        height: u32,
        format: ImageFormat,
        is_opaque: bool,
        allow_mipmaps: bool,
    ) -> Self {
        ImageDescriptor {
            width,
            height,
            format,
            stride: None,
            offset: 0,
            is_opaque,
            allow_mipmaps,
        }
    }

    pub fn compute_stride(&self) -> u32 {
        self.stride
            .unwrap_or(self.width * self.format.bytes_per_pixel())
    }

    pub fn compute_total_size(&self) -> u32 {
        self.compute_stride() * self.height
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ImageData {
    Raw(#[serde(with = "serde_image_data_raw")] Arc<Vec<u8>>),
    Blob(#[serde(with = "serde_bytes")] BlobImageData),
    External(ExternalImageData),
}

mod serde_image_data_raw {
    extern crate serde_bytes;

    use std::sync::Arc;
    use serde::{Deserializer, Serializer};

    pub fn serialize<'a, S: Serializer>(bytes: &'a Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error> {
        serde_bytes::serialize(bytes.as_slice(), serializer)
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Arc<Vec<u8>>, D::Error> {
        serde_bytes::deserialize(deserializer).map(Arc::new)
    }
}

impl ImageData {
    pub fn new(bytes: Vec<u8>) -> Self {
        ImageData::Raw(Arc::new(bytes))
    }

    pub fn new_shared(bytes: Arc<Vec<u8>>) -> Self {
        ImageData::Raw(bytes)
    }

    pub fn new_blob_image(commands: Vec<u8>) -> Self {
        ImageData::Blob(commands)
    }

    #[inline]
    pub fn is_blob(&self) -> bool {
        match *self {
            ImageData::Blob(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn uses_texture_cache(&self) -> bool {
        match *self {
            ImageData::External(ref ext_data) => match ext_data.image_type {
                ExternalImageType::TextureHandle(_) => false,
                ExternalImageType::Buffer => true,
            },
            ImageData::Blob(_) => true,
            ImageData::Raw(_) => true,
        }
    }
}

pub trait BlobImageResources {
    fn get_font_data(&self, key: FontKey) -> &FontTemplate;
    fn get_image(&self, key: ImageKey) -> Option<(&ImageData, &ImageDescriptor)>;
}

pub trait BlobImageRenderer: Send {
    fn add(&mut self, key: ImageKey, data: BlobImageData, tiling: Option<TileSize>);

    fn update(&mut self, key: ImageKey, data: BlobImageData, dirty_rect: Option<DeviceUintRect>);

    fn delete(&mut self, key: ImageKey);

    fn request(
        &mut self,
        services: &BlobImageResources,
        key: BlobImageRequest,
        descriptor: &BlobImageDescriptor,
        dirty_rect: Option<DeviceUintRect>,
    );

    fn resolve(&mut self, key: BlobImageRequest) -> BlobImageResult;

    fn delete_font(&mut self, key: FontKey);

    fn delete_font_instance(&mut self, key: FontInstanceKey);

    fn clear_namespace(&mut self, namespace: IdNamespace);
}

pub type BlobImageData = Vec<u8>;

pub type BlobImageResult = Result<RasterizedBlobImage, BlobImageError>;

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct BlobImageDescriptor {
    pub width: u32,
    pub height: u32,
    pub offset: DevicePoint,
    pub format: ImageFormat,
}

pub struct RasterizedBlobImage {
    pub width: u32,
    pub height: u32,
    pub data: Vec<u8>,
}

#[derive(Clone, Debug)]
pub enum BlobImageError {
    Oom,
    InvalidKey,
    InvalidData,
    Other(String),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct BlobImageRequest {
    pub key: ImageKey,
    pub tile: Option<TileOffset>,
}
<commit_msg>webrender_api: image serialize: Remove elidable lifetime.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate serde_bytes;

use font::{FontInstanceKey, FontKey, FontTemplate};
use std::sync::Arc;
use {DevicePoint, DeviceUintRect, IdNamespace, TileOffset, TileSize};

#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ImageKey(pub IdNamespace, pub u32);

impl ImageKey {
    pub const DUMMY: Self = ImageKey(IdNamespace(0), 0);

    pub fn new(namespace: IdNamespace, key: u32) -> Self {
        ImageKey(namespace, key)
    }
}

/// An arbitrary identifier for an external image provided by the
/// application. It must be a unique identifier for each external
/// image.
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ExternalImageId(pub u64);

#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum TextureTarget {
    Default = 0,
    Array = 1,
    Rect = 2,
    External = 3,
}

#[repr(u32)]
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum ExternalImageType {
    TextureHandle(TextureTarget),
    Buffer,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ExternalImageData {
    pub id: ExternalImageId,
    pub channel_index: u8,
    pub image_type: ExternalImageType,
}

#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ImageFormat {
    R8 = 1,
    BGRA8 = 3,
    RGBAF32 = 4,
    RG8 = 5,
}

impl ImageFormat {
    pub fn bytes_per_pixel(self) -> u32 {
        match self {
            ImageFormat::R8 => 1,
            ImageFormat::BGRA8 => 4,
            ImageFormat::RGBAF32 => 16,
            ImageFormat::RG8 => 2,
        }
    }
}

#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageDescriptor {
    pub format: ImageFormat,
    pub width: u32,
    pub height: u32,
    pub stride: Option<u32>,
    pub offset: u32,
    pub is_opaque: bool,
    pub allow_mipmaps: bool,
}

impl ImageDescriptor {
    pub fn new(
        width: u32,
        height: u32,
        format: ImageFormat,
        is_opaque: bool,
        allow_mipmaps: bool,
    ) -> Self {
        ImageDescriptor {
            width,
            height,
            format,
            stride: None,
            offset: 0,
            is_opaque,
            allow_mipmaps,
        }
    }

    pub fn compute_stride(&self) -> u32 {
        self.stride
            .unwrap_or(self.width * self.format.bytes_per_pixel())
    }

    pub fn compute_total_size(&self) -> u32 {
        self.compute_stride() * self.height
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ImageData {
    Raw(#[serde(with = "serde_image_data_raw")] Arc<Vec<u8>>),
    Blob(#[serde(with = "serde_bytes")] BlobImageData),
    External(ExternalImageData),
}

mod serde_image_data_raw {
    extern crate serde_bytes;

    use std::sync::Arc;
    use serde::{Deserializer, Serializer};

    pub fn serialize<S: Serializer>(bytes: &Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error> {
        serde_bytes::serialize(bytes.as_slice(), serializer)
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Arc<Vec<u8>>, D::Error> {
        serde_bytes::deserialize(deserializer).map(Arc::new)
    }
}

impl ImageData {
    pub fn new(bytes: Vec<u8>) -> Self {
        ImageData::Raw(Arc::new(bytes))
    }

    pub fn new_shared(bytes: Arc<Vec<u8>>) -> Self {
        ImageData::Raw(bytes)
    }

    pub fn new_blob_image(commands: Vec<u8>) -> Self {
        ImageData::Blob(commands)
    }

    #[inline]
    pub fn is_blob(&self) -> bool {
        match *self {
            ImageData::Blob(_) => true,
            _ => false,
        }
    }

    #[inline]
    pub fn uses_texture_cache(&self) -> bool {
        match *self {
            ImageData::External(ref ext_data) => match ext_data.image_type {
                ExternalImageType::TextureHandle(_) => false,
                ExternalImageType::Buffer => true,
            },
            ImageData::Blob(_) => true,
            ImageData::Raw(_) => true,
        }
    }
}

pub trait BlobImageResources {
    fn get_font_data(&self, key: FontKey) -> &FontTemplate;
    fn get_image(&self, key: ImageKey) -> Option<(&ImageData, &ImageDescriptor)>;
}

pub trait BlobImageRenderer: Send {
    fn add(&mut self, key: ImageKey, data: BlobImageData, tiling: Option<TileSize>);

    fn update(&mut self, key: ImageKey, data: BlobImageData, dirty_rect: Option<DeviceUintRect>);

    fn delete(&mut self, key: ImageKey);

    fn request(
        &mut self,
        services: &BlobImageResources,
        key: BlobImageRequest,
        descriptor: &BlobImageDescriptor,
        dirty_rect: Option<DeviceUintRect>,
    );

    fn resolve(&mut self, key: BlobImageRequest) -> BlobImageResult;

    fn delete_font(&mut self, key: FontKey);

    fn delete_font_instance(&mut self, key: FontInstanceKey);

    fn clear_namespace(&mut self, namespace: IdNamespace);
}

pub type BlobImageData = Vec<u8>;

pub type BlobImageResult = Result<RasterizedBlobImage, BlobImageError>;

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct BlobImageDescriptor {
    pub width: u32,
    pub height: u32,
    pub offset: DevicePoint,
    pub format: ImageFormat,
}

pub struct RasterizedBlobImage {
    pub width: u32,
    pub height: u32,
    pub data: Vec<u8>,
}

#[derive(Clone, Debug)]
pub enum BlobImageError {
    Oom,
    InvalidKey,
    InvalidData,
    Other(String),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct BlobImageRequest {
    pub key: ImageKey,
    pub tile: Option<TileOffset>,
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::collections::HashMap;

use serde_json::{to_value, Value};

use context::get_json_pointer;
use errors::Result;
use renderer::for_loop::{ForLoop, ForLoopState};
use renderer::stack_frame::{FrameContext, FrameType, StackFrame, Val};
use template::Template;

/// Contains the user data and allows no mutation
#[derive(Debug)]
pub struct UserContext<'a> {
    /// Read-only context
    inner: &'a Value,
}

impl<'a> UserContext<'a> {
    /// Create an immutable user context to be used in the call stack
    pub fn new(context: &'a Value) -> Self {
        UserContext { inner: context }
    }

    pub fn find_value(&self, key: &str) -> Option<&'a Value> {
        self.inner.get(key)
    }

    pub fn find_value_by_pointer(self: &Self, pointer: &str) -> Option<&'a Value> {
        self.inner.pointer(pointer)
    }
}

/// Contains the stack of frames
#[derive(Debug)]
pub struct CallStack<'a> {
    /// The stack of frames
    stack: Vec<StackFrame<'a>>,
    /// User supplied context for the render
    context: UserContext<'a>,
}

impl<'a> CallStack<'a> {
    /// Create the initial call stack
    pub fn new(context: &'a Value, template: &'a Template) -> CallStack<'a> {
        CallStack {
            stack: vec![StackFrame::new(FrameType::Origin, "ORIGIN", template)],
            context: UserContext::new(context),
        }
    }

    pub fn push_for_loop_frame(&mut self, name: &'a str, for_loop: ForLoop<'a>) {
        let tpl = self.stack.last().expect("Stack frame").active_template;
        self.stack.push(StackFrame::new_for_loop(name, tpl, for_loop));
    }

    pub fn push_macro_frame(
        &mut self,
        namespace: &'a str,
        name: &'a str,
        context: FrameContext<'a>,
        tpl: &'a Template,
    ) {
        self.stack.push(StackFrame::new_macro(name, tpl, namespace, context));
    }

    pub fn push_include_frame(&mut self, name: &'a str, tpl: &'a Template) {
        self.stack.push(StackFrame::new_include(name, tpl));
    }

    /// Returns mutable reference to global `StackFrame`
    /// i.e gets first stack outside current for loops
    pub fn global_frame_mut(self: &mut Self) -> &mut StackFrame<'a> {
        if self.current_frame().kind == FrameType::ForLoop {
            for stack_frame in self.stack.iter_mut().rev() {
                // walk up the parent stacks until we meet the current template
                if stack_frame.kind != FrameType::ForLoop {
                    return stack_frame;
                }
            }
            unreachable!("Global frame not found when trying to break out of for loop");
        } else {
            // Macro, Origin, or Include
            return self.current_frame_mut();
        }
    }

    /// Returns mutable reference to current `StackFrame`
    pub fn current_frame_mut(self: &mut Self) -> &mut StackFrame<'a> {
        self.stack.last_mut().expect("No current frame exists")
    }

    /// Returns immutable reference to current `StackFrame`
    pub fn current_frame(self: &Self) -> &StackFrame<'a> {
        self.stack.last().expect("No current frame exists")
    }

    /// Pop the last frame
    pub fn pop(&mut self) {
        self.stack.pop().expect("Mistakenly popped Origin frame");
    }

    pub fn lookup(&self, key: &str) -> Option<Val<'a>> {
        for stack_frame in self.stack.iter().rev() {
            let found = stack_frame.find_value(key);
            if found.is_some() {
                return found;
            }

            // If we looked in a macro or origin frame, no point continuing
            // Origin is the last one and macro frame don't have access to parent frames
            if stack_frame.kind == FrameType::Macro || stack_frame.kind == FrameType::Origin {
                break;
            }
        }

        // Not in stack frame, look in user supplied context
        if key.contains('.') {
            return self
                .context
                .find_value_by_pointer(&get_json_pointer(key))
                .map(|v| Cow::Borrowed(v));
        } else if let Some(value) = self.context.find_value(key) {
            return Some(Cow::Borrowed(value));
        }

        None
    }

    /// Add an assignment value (via {% set ... %} and {% set_global ... %} )
    pub fn add_assignment(&mut self, key: &'a str, global: bool, value: Val<'a>) {
        if global {
            self.global_frame_mut().insert(key, value);
        } else {
            self.current_frame_mut().insert(key, value);
        }
    }

    /// Breaks current for loop
    pub fn break_for_loop(self: &mut Self) -> Result<()> {
        match self.current_frame_mut().for_loop {
            Some(ref mut for_loop) => {
                for_loop.break_loop();
                Ok(())
            }
            None => bail!("Attempted `break` while not in `for loop`"),
        }
    }

    /// Continues current for loop
    pub fn increment_for_loop(self: &mut Self) -> Result<()> {
        let frame = self.current_frame_mut();
        frame.clear_context();
        match frame.for_loop {
            Some(ref mut for_loop) => {
                for_loop.increment();
                Ok(())
            }
            None => bail!("Attempted `increment` while not in `for loop`"),
        }
    }

    /// Continues current for loop
    pub fn continue_for_loop(self: &mut Self) -> Result<()> {
        match self.current_frame_mut().for_loop {
            Some(ref mut for_loop) => {
                for_loop.continue_loop();
                Ok(())
            }
            None => bail!("Attempted `continue` while not in `for loop`"),
        }
    }

    /// True if should break body, applicable to `break` and `continue`
    pub fn should_break_body(&self) -> bool {
        match self.current_frame().for_loop {
            Some(ref for_loop) => {
                for_loop.state == ForLoopState::Break || for_loop.state == ForLoopState::Continue
            }
            None => false,
        }
    }

    /// True if should break loop, applicable to `break` only
    pub fn should_break_for_loop(&self) -> bool {
        match self.current_frame().for_loop {
            Some(ref for_loop) => for_loop.state == ForLoopState::Break,
            None => false,
        }
    }

    /// Grab the current frame template
    pub fn active_template(&self) -> &'a Template {
        self.current_frame().active_template
    }

    pub fn current_context_cloned(self: &Self) -> Value {
        let mut context = HashMap::new();

        // Go back the stack in reverse to see what we have access to
        for frame in self.stack.iter().rev() {
            context.extend(frame.context_owned());
            if let Some(ref for_loop) = frame.for_loop {
                context.insert(
                    for_loop.value_name.to_string(),
                    for_loop.get_current_value().into_owned(),
                );
                if for_loop.is_key_value() {
                    context.insert(
                        for_loop.key_name.clone().unwrap(),
                        Value::String(for_loop.get_current_key()),
                    );
                }
            }
            // Macros don't have access to the user context, we're done
            if frame.kind == FrameType::Macro {
                return to_value(&context).unwrap();
            }
        }

        // If we are here we take the user context
        // and add the values found in the stack to it.
        // We do it this way as we can override global variable temporarily in forloops
        match self.context.inner.clone() {
            Value::Object(mut m) => {
                for (key, val) in context {
                    m.insert(key.to_string(), val);
                }

                Value::Object(m)
            }
            _ => unreachable!("Had a context that wasn't a map?!"),
        }
    }
}
<commit_msg>Clippy fix<commit_after>use std::borrow::Cow;
use std::collections::HashMap;

use serde_json::{to_value, Value};

use context::get_json_pointer;
use errors::Result;
use renderer::for_loop::{ForLoop, ForLoopState};
use renderer::stack_frame::{FrameContext, FrameType, StackFrame, Val};
use template::Template;

/// Contains the user data and allows no mutation
#[derive(Debug)]
pub struct UserContext<'a> {
    /// Read-only context
    inner: &'a Value,
}

impl<'a> UserContext<'a> {
    /// Create an immutable user context to be used in the call stack
    pub fn new(context: &'a Value) -> Self {
        UserContext { inner: context }
    }

    pub fn find_value(&self, key: &str) -> Option<&'a Value> {
        self.inner.get(key)
    }

    pub fn find_value_by_pointer(self: &Self, pointer: &str) -> Option<&'a Value> {
        self.inner.pointer(pointer)
    }
}

/// Contains the stack of frames
#[derive(Debug)]
pub struct CallStack<'a> {
    /// The stack of frames
    stack: Vec<StackFrame<'a>>,
    /// User supplied context for the render
    context: UserContext<'a>,
}

impl<'a> CallStack<'a> {
    /// Create the initial call stack
    pub fn new(context: &'a Value, template: &'a Template) -> CallStack<'a> {
        CallStack {
            stack: vec![StackFrame::new(FrameType::Origin, "ORIGIN", template)],
            context: UserContext::new(context),
        }
    }

    pub fn push_for_loop_frame(&mut self, name: &'a str, for_loop: ForLoop<'a>) {
        let tpl = self.stack.last().expect("Stack frame").active_template;
        self.stack.push(StackFrame::new_for_loop(name, tpl, for_loop));
    }

    pub fn push_macro_frame(
        &mut self,
        namespace: &'a str,
        name: &'a str,
        context: FrameContext<'a>,
        tpl: &'a Template,
    ) {
        self.stack.push(StackFrame::new_macro(name, tpl, namespace, context));
    }

    pub fn push_include_frame(&mut self, name: &'a str, tpl: &'a Template) {
        self.stack.push(StackFrame::new_include(name, tpl));
    }

    /// Returns mutable reference to global `StackFrame`
    /// i.e gets first stack outside current for loops
    pub fn global_frame_mut(self: &mut Self) -> &mut StackFrame<'a> {
        if self.current_frame().kind == FrameType::ForLoop {
            for stack_frame in self.stack.iter_mut().rev() {
                // walk up the parent stacks until we meet the current template
                if stack_frame.kind != FrameType::ForLoop {
                    return stack_frame;
                }
            }
            unreachable!("Global frame not found when trying to break out of for loop");
        } else {
            // Macro, Origin, or Include
            self.current_frame_mut()
        }
    }

    /// Returns mutable reference to current `StackFrame`
    pub fn current_frame_mut(self: &mut Self) -> &mut StackFrame<'a> {
        self.stack.last_mut().expect("No current frame exists")
    }

    /// Returns immutable reference to current `StackFrame`
    pub fn current_frame(self: &Self) -> &StackFrame<'a> {
        self.stack.last().expect("No current frame exists")
    }

    /// Pop the last frame
    pub fn pop(&mut self) {
        self.stack.pop().expect("Mistakenly popped Origin frame");
    }

    pub fn lookup(&self, key: &str) -> Option<Val<'a>> {
        for stack_frame in self.stack.iter().rev() {
            let found = stack_frame.find_value(key);
            if found.is_some() {
                return found;
            }

            // If we looked in a macro or origin frame, no point continuing
            // Origin is the last one and macro frame don't have access to parent frames
            if stack_frame.kind == FrameType::Macro || stack_frame.kind == FrameType::Origin {
                break;
            }
        }

        // Not in stack frame, look in user supplied context
        if key.contains('.') {
            return self
                .context
                .find_value_by_pointer(&get_json_pointer(key))
                .map(|v| Cow::Borrowed(v));
        } else if let Some(value) = self.context.find_value(key) {
            return Some(Cow::Borrowed(value));
        }

        None
    }

    /// Add an assignment value (via {% set ... %} and {% set_global ... %} )
    pub fn add_assignment(&mut self, key: &'a str, global: bool, value: Val<'a>) {
        if global {
            self.global_frame_mut().insert(key, value);
        } else {
            self.current_frame_mut().insert(key, value);
        }
    }

    /// Breaks current for loop
    pub fn break_for_loop(self: &mut Self) -> Result<()> {
        match self.current_frame_mut().for_loop {
            Some(ref mut for_loop) => {
                for_loop.break_loop();
                Ok(())
            }
            None => bail!("Attempted `break` while not in `for loop`"),
        }
    }

    /// Continues current for loop
    pub fn increment_for_loop(self: &mut Self) -> Result<()> {
        let frame = self.current_frame_mut();
        frame.clear_context();
        match frame.for_loop {
            Some(ref mut for_loop) => {
                for_loop.increment();
                Ok(())
            }
            None => bail!("Attempted `increment` while not in `for loop`"),
        }
    }

    /// Continues current for loop
    pub fn continue_for_loop(self: &mut Self) -> Result<()> {
        match self.current_frame_mut().for_loop {
            Some(ref mut for_loop) => {
                for_loop.continue_loop();
                Ok(())
            }
            None => bail!("Attempted `continue` while not in `for loop`"),
        }
    }

    /// True if should break body, applicable to `break` and `continue`
    pub fn should_break_body(&self) -> bool {
        match self.current_frame().for_loop {
            Some(ref for_loop) => {
                for_loop.state == ForLoopState::Break || for_loop.state == ForLoopState::Continue
            }
            None => false,
        }
    }

    /// True if should break loop, applicable to `break` only
    pub fn should_break_for_loop(&self) -> bool {
        match self.current_frame().for_loop {
            Some(ref for_loop) => for_loop.state == ForLoopState::Break,
            None => false,
        }
    }

    /// Grab the current frame template
    pub fn active_template(&self) -> &'a Template {
        self.current_frame().active_template
    }

    pub fn current_context_cloned(self: &Self) -> Value {
        let mut context = HashMap::new();

        // Go back the stack in reverse to see what we have access to
        for frame in self.stack.iter().rev() {
            context.extend(frame.context_owned());
            if let Some(ref for_loop) = frame.for_loop {
                context.insert(
                    for_loop.value_name.to_string(),
                    for_loop.get_current_value().into_owned(),
                );
                if for_loop.is_key_value() {
                    context.insert(
                        for_loop.key_name.clone().unwrap(),
                        Value::String(for_loop.get_current_key()),
                    );
                }
            }
            // Macros don't have access to the user context, we're done
            if frame.kind == FrameType::Macro {
                return to_value(&context).unwrap();
            }
        }

        // If we are here we take the user context
        // and add the values found in the stack to it.
        // We do it this way as we can override global variable temporarily in forloops
        match self.context.inner.clone() {
            Value::Object(mut m) => {
                for (key, val) in context {
                    m.insert(key.to_string(), val);
                }

                Value::Object(m)
            }
            _ => unreachable!("Had a context that wasn't a map?!"),
        }
    }
}
<|endoftext|>


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

#![cfg(feature = "extra-traits")]

extern crate proc_macro2;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro2::Delimiter::*;
use proc_macro2::{Delimiter, Group, Op, Spacing, Span, Term, TokenStream, TokenTree};
use syn::{AttrStyle, Attribute, Lit};

fn alone(c: char) -> TokenTree {
    Op::new(c, Spacing::Alone).into()
}

fn joint(c: char) -> TokenTree {
    Op::new(c, Spacing::Joint).into()
}

fn delimited(delim: Delimiter, tokens: Vec<TokenTree>) -> TokenTree {
    Group::new(delim, tokens.into_iter().collect()).into()
}

fn word(sym: &str) -> TokenTree {
    Term::new(sym, Span::call_site()).into()
}

#[test]
fn test_struct() {
    let raw = "
        #[derive(Debug, Clone)]
        pub struct Item {
            pub ident: Ident,
            pub attrs: Vec<Attribute>,
        }
    ";

    let expected = vec![
        alone('#'),
        delimited(
            Bracket,
            vec![
                word("derive"),
                delimited(Parenthesis, vec![word("Debug"), alone(','), word("Clone")]),
            ],
        ),
        word("pub"),
        word("struct"),
        word("Item"),
        delimited(
            Brace,
            vec![
                word("pub"),
                word("ident"),
                alone(':'),
                word("Ident"),
                alone(','),
                word("pub"),
                word("attrs"),
                alone(':'),
                word("Vec"),
                alone('<'),
                word("Attribute"),
                joint('>'),
                alone(','),
            ],
        ),
    ];

    fn wrap(tts: TokenStream) -> Attribute {
        Attribute {
            style: AttrStyle::Outer,
            pound_token: Default::default(),
            bracket_token: Default::default(),
            path: "test".into(),
            tts,
            is_sugared_doc: false,
        }
    }

    let result = wrap(raw.parse().unwrap());
    let expected = wrap(expected.into_iter().collect());
    if result != expected {
        panic!("{:#?}\n!=\n{:#?}", result.tts, expected.tts);
    }
}

#[test]
fn test_literal_mangling() {
    let raw = "0_4";
    let parsed: Lit = syn::parse_str(raw).unwrap();
    assert_eq!(raw, quote!(#parsed).to_string());
}
<commit_msg>Fix test_token_trees<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg(feature = "extra-traits")]

extern crate proc_macro2;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro2::Delimiter::*;
use proc_macro2::*;
use syn::{AttrStyle, Attribute, Lit};

fn alone(c: char) -> TokenTree {
    Punct::new(c, Spacing::Alone).into()
}

fn joint(c: char) -> TokenTree {
    Punct::new(c, Spacing::Joint).into()
}

fn delimited(delim: Delimiter, tokens: Vec<TokenTree>) -> TokenTree {
    Group::new(delim, tokens.into_iter().collect()).into()
}

fn word(sym: &str) -> TokenTree {
    Ident::new(sym, Span::call_site()).into()
}

#[test]
fn test_struct() {
    let raw = "
        #[derive(Debug, Clone)]
        pub struct Item {
            pub ident: Ident,
            pub attrs: Vec<Attribute>,
        }
    ";

    let expected = vec![
        alone('#'),
        delimited(
            Bracket,
            vec![
                word("derive"),
                delimited(Parenthesis, vec![word("Debug"), alone(','), word("Clone")]),
            ],
        ),
        word("pub"),
        word("struct"),
        word("Item"),
        delimited(
            Brace,
            vec![
                word("pub"),
                word("ident"),
                alone(':'),
                word("Ident"),
                alone(','),
                word("pub"),
                word("attrs"),
                alone(':'),
                word("Vec"),
                alone('<'),
                word("Attribute"),
                joint('>'),
                alone(','),
            ],
        ),
    ];

    fn wrap(tts: TokenStream) -> Attribute {
        Attribute {
            style: AttrStyle::Outer,
            pound_token: Default::default(),
            bracket_token: Default::default(),
            path: Ident::new("test", Span::call_site()).into(),
            tts,
            is_sugared_doc: false,
        }
    }

    let result = wrap(raw.parse().unwrap());
    let expected = wrap(expected.into_iter().collect());
    if result != expected {
        panic!("{:#?}\n!=\n{:#?}", result.tts, expected.tts);
    }
}

#[test]
fn test_literal_mangling() {
    let raw = "0_4";
    let parsed: Lit = syn::parse_str(raw).unwrap();
    assert_eq!(raw, quote!(#parsed).to_string());
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

use crate::*;
use core::mem;

/// Can override options used by a [`Formatter`]
///
/// [`Formatter`]: trait.Formatter.html
pub trait FormatterOptionsProvider {
	/// Called by the formatter. The method can override any options before the formatter uses them.
	///
	/// # Arguments
	///
	/// - `instruction`: Instruction
	/// - `operand`: Operand number, 0-based. This is a formatter operand and isn't necessarily the same as an instruction operand.
	/// - `instruction_operand`: Instruction operand number, 0-based, or `None` if it's an operand created by the formatter.
	/// - `options`: Options. Only those options that will be used by the formatter are initialized.
	/// - `number_options`: Number formatting options
	fn operand_options(
		&mut self, instruction: &Instruction, operand: u32, instruction_operand: Option<u32>, options: &mut FormatterOperandOptions,
		number_options: &mut NumberFormattingOptions<'_>,
	);
}

pub(super) struct FormatterOperandOptionsFlags;
impl FormatterOperandOptionsFlags {
	#[cfg(any(feature = "intel", feature = "masm", feature = "nasm"))]
	pub(super) const NONE: u32 = 0x0000_0000;
	pub(super) const NO_BRANCH_SIZE: u32 = 0x0000_0001;
	const RIP_RELATIVE_ADDRESSES: u32 = 0x0000_0002;
	const MEMORY_SIZE_SHIFT: u32 = 30;
	const MEMORY_SIZE_MASK: u32 = 3 << FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT;
}

/// Operand options
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct FormatterOperandOptions {
	flags: u32, // FormatterOperandOptionsFlags
}

impl FormatterOperandOptions {
	#[cfg(any(feature = "intel", feature = "masm", feature = "nasm"))]
	#[must_use]
	#[inline]
	pub(super) const fn new(flags: u32) -> Self {
		Self { flags }
	}

	#[must_use]
	#[inline]
	pub(super) const fn with_memory_size_options(options: MemorySizeOptions) -> Self {
		Self { flags: (options as u32) << FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT }
	}

	/// Show branch size (eg. `SHORT`, `NEAR PTR`)
	#[must_use]
	#[inline]
	pub const fn branch_size(&self) -> bool {
		(self.flags & FormatterOperandOptionsFlags::NO_BRANCH_SIZE) == 0
	}

	/// Show branch size (eg. `SHORT`, `NEAR PTR`)
	///
	/// # Arguments
	///
	/// - `value`: New value
	#[inline]
	pub fn set_branch_size(&mut self, value: bool) {
		if value {
			self.flags &= !FormatterOperandOptionsFlags::NO_BRANCH_SIZE;
		} else {
			self.flags |= FormatterOperandOptionsFlags::NO_BRANCH_SIZE;
		}
	}

	/// If `true`, show `RIP` relative addresses as `[rip+12345678h]`, else show the linear address eg. `[1029384756AFBECDh]`
	#[must_use]
	#[inline]
	pub const fn rip_relative_addresses(&self) -> bool {
		(self.flags & FormatterOperandOptionsFlags::RIP_RELATIVE_ADDRESSES) != 0
	}

	/// If `true`, show `RIP` relative addresses as `[rip+12345678h]`, else show the linear address eg. `[1029384756AFBECDh]`
	///
	/// # Arguments
	///
	/// - `value`: New value
	#[inline]
	pub fn set_rip_relative_addresses(&mut self, value: bool) {
		if value {
			self.flags |= FormatterOperandOptionsFlags::RIP_RELATIVE_ADDRESSES;
		} else {
			self.flags &= !FormatterOperandOptionsFlags::RIP_RELATIVE_ADDRESSES;
		}
	}

	/// Memory size options
	#[must_use]
	#[inline]
	pub const fn memory_size_options(&self) -> MemorySizeOptions {
		// SAFETY: the bits can only be a valid enum value
		unsafe { mem::transmute((self.flags >> FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT) as MemorySizeOptionsUnderlyingType) }
	}

	/// Memory size options
	///
	/// # Arguments
	///
	/// - `value`: New value
	#[inline]
	pub fn set_memory_size_options(&mut self, value: MemorySizeOptions) {
		self.flags =
			(self.flags & !FormatterOperandOptionsFlags::MEMORY_SIZE_MASK) | ((value as u32) << FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT)
	}
}
<commit_msg>Remove `const` from transmute function<commit_after>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

use crate::*;
use core::mem;

/// Can override options used by a [`Formatter`]
///
/// [`Formatter`]: trait.Formatter.html
pub trait FormatterOptionsProvider {
	/// Called by the formatter. The method can override any options before the formatter uses them.
	///
	/// # Arguments
	///
	/// - `instruction`: Instruction
	/// - `operand`: Operand number, 0-based. This is a formatter operand and isn't necessarily the same as an instruction operand.
	/// - `instruction_operand`: Instruction operand number, 0-based, or `None` if it's an operand created by the formatter.
	/// - `options`: Options. Only those options that will be used by the formatter are initialized.
	/// - `number_options`: Number formatting options
	fn operand_options(
		&mut self, instruction: &Instruction, operand: u32, instruction_operand: Option<u32>, options: &mut FormatterOperandOptions,
		number_options: &mut NumberFormattingOptions<'_>,
	);
}

pub(super) struct FormatterOperandOptionsFlags;
impl FormatterOperandOptionsFlags {
	#[cfg(any(feature = "intel", feature = "masm", feature = "nasm"))]
	pub(super) const NONE: u32 = 0x0000_0000;
	pub(super) const NO_BRANCH_SIZE: u32 = 0x0000_0001;
	const RIP_RELATIVE_ADDRESSES: u32 = 0x0000_0002;
	const MEMORY_SIZE_SHIFT: u32 = 30;
	const MEMORY_SIZE_MASK: u32 = 3 << FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT;
}

/// Operand options
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct FormatterOperandOptions {
	flags: u32, // FormatterOperandOptionsFlags
}

impl FormatterOperandOptions {
	#[cfg(any(feature = "intel", feature = "masm", feature = "nasm"))]
	#[must_use]
	#[inline]
	pub(super) const fn new(flags: u32) -> Self {
		Self { flags }
	}

	#[must_use]
	#[inline]
	pub(super) const fn with_memory_size_options(options: MemorySizeOptions) -> Self {
		Self { flags: (options as u32) << FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT }
	}

	/// Show branch size (eg. `SHORT`, `NEAR PTR`)
	#[must_use]
	#[inline]
	pub const fn branch_size(&self) -> bool {
		(self.flags & FormatterOperandOptionsFlags::NO_BRANCH_SIZE) == 0
	}

	/// Show branch size (eg. `SHORT`, `NEAR PTR`)
	///
	/// # Arguments
	///
	/// - `value`: New value
	#[inline]
	pub fn set_branch_size(&mut self, value: bool) {
		if value {
			self.flags &= !FormatterOperandOptionsFlags::NO_BRANCH_SIZE;
		} else {
			self.flags |= FormatterOperandOptionsFlags::NO_BRANCH_SIZE;
		}
	}

	/// If `true`, show `RIP` relative addresses as `[rip+12345678h]`, else show the linear address eg. `[1029384756AFBECDh]`
	#[must_use]
	#[inline]
	pub const fn rip_relative_addresses(&self) -> bool {
		(self.flags & FormatterOperandOptionsFlags::RIP_RELATIVE_ADDRESSES) != 0
	}

	/// If `true`, show `RIP` relative addresses as `[rip+12345678h]`, else show the linear address eg. `[1029384756AFBECDh]`
	///
	/// # Arguments
	///
	/// - `value`: New value
	#[inline]
	pub fn set_rip_relative_addresses(&mut self, value: bool) {
		if value {
			self.flags |= FormatterOperandOptionsFlags::RIP_RELATIVE_ADDRESSES;
		} else {
			self.flags &= !FormatterOperandOptionsFlags::RIP_RELATIVE_ADDRESSES;
		}
	}

	/// Memory size options
	#[must_use]
	#[inline]
	pub fn memory_size_options(&self) -> MemorySizeOptions {
		// SAFETY: the bits can only be a valid enum value
		unsafe { mem::transmute((self.flags >> FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT) as MemorySizeOptionsUnderlyingType) }
	}

	/// Memory size options
	///
	/// # Arguments
	///
	/// - `value`: New value
	#[inline]
	pub fn set_memory_size_options(&mut self, value: MemorySizeOptions) {
		self.flags =
			(self.flags & !FormatterOperandOptionsFlags::MEMORY_SIZE_MASK) | ((value as u32) << FormatterOperandOptionsFlags::MEMORY_SIZE_SHIFT)
	}
}
<|endoftext|>