<commit_before>use std::{cmp::min, env, fs::File, io, mem, time::Duration};

use pgn_reader::{BufferedReader, Color, RawHeader, SanPlus, Skip, Visitor};
use rand::{distributions::OpenClosed01, rngs::SmallRng, Rng, SeedableRng};
use serde::Serialize;
use serde_with::{serde_as, DisplayFromStr, SpaceSeparator, StringWithSeparator};

const BATCH_SIZE: usize = 50;

#[derive(Debug, Serialize, Copy, Clone)]
#[serde(rename_all = "camelCase")]
enum Speed {
    UltraBullet,
    Bullet,
    Blitz,
    Rapid,
    Classical,
    Correspondence,
}

impl Speed {
    fn from_seconds_and_increment(seconds: u64, increment: u64) -> Speed {
        let total = seconds + 40 * increment;

        if total < 30 {
            Speed::UltraBullet
        } else if total < 180 {
            Speed::Bullet
        } else if total < 480 {
            Speed::Blitz
        } else if total < 1500 {
            Speed::Rapid
        } else if total < 21_600 {
            Speed::Classical
        } else {
            Speed::Correspondence
        }
    }

    fn from_bytes(bytes: &[u8]) -> Result<Speed, ()> {
        if bytes == b"-" {
            return Ok(Speed::Correspondence);
        }

        let mut parts = bytes.splitn(2, |ch| *ch == b'+');
        let seconds = btoi::btou(parts.next().ok_or(())?).map_err(|_| ())?;
        let increment = btoi::btou(parts.next().ok_or(())?).map_err(|_| ())?;
        Ok(Speed::from_seconds_and_increment(seconds, increment))
    }
}

struct Importer {
    filename: String,
    client: reqwest::blocking::Client,
    rng: SmallRng,

    current: Game,
    skip: bool,
    batch: Vec<Game>,
}

#[serde_as]
#[derive(Default, Serialize, Debug)]
struct Game {
    variant: Option<String>,
    speed: Option<Speed>,
    fen: Option<String>,
    id: Option<String>,
    date: Option<String>,
    white: Player,
    black: Player,
    #[serde_as(as = "Option<DisplayFromStr>")]
    winner: Option<Color>,
    #[serde_as(as = "StringWithSeparator<SpaceSeparator, SanPlus>")]
    moves: Vec<SanPlus>,
}

#[derive(Default, Serialize, Debug)]
struct Player {
    name: Option<String>,
    rating: Option<u16>,
}

impl Importer {
    fn new(filename: String) -> Importer {
        Importer {
            filename,
            client: reqwest::blocking::Client::builder()
                .timeout(Duration::from_secs(60))
                .build()
                .expect("client"),
            rng: SmallRng::from_seed([
                0x19, 0x29, 0xab, 0x17, 0xc6, 0xfa, 0xb0, 0xe9, 0x4b, 0x44, 0xd8, 0x07, 0x09, 0xbf,
                0x1d, 0x87, 0xbd, 0xd8, 0xb3, 0x2f, 0xe1, 0xe2, 0xa0, 0x1a, 0x9e, 0x30, 0x98, 0xd7,
                0xef, 0xd5, 0x7a, 0x1d,
            ]),
            current: Game::default(),
            skip: false,
            batch: Vec::with_capacity(BATCH_SIZE),
        }
    }

    pub fn send(&mut self) {
        // println!("{}", serde_json::to_string(&self.batch).expect("serialize"));

        let res = self
            .client
            .put("http://127.0.0.1:9001/import/lichess")
            .json(&self.batch)
            .send()
            .expect("send batch");

        println!(
            "{}: {}: {} - {}",
            self.filename,
            self.batch
                .last()
                .and_then(|g| g.date.as_ref())
                .unwrap_or(&String::new()),
            res.status(),
            res.text().expect("decode response")
        );

        self.batch.clear();
    }
}

impl Visitor for Importer {
    type Result = ();

    fn begin_game(&mut self) {
        self.skip = false;
        self.current = Game::default();
    }

    fn header(&mut self, key: &[u8], value: RawHeader<'_>) {
        if key == b"White" {
            self.current.white.name = Some(value.decode_utf8().expect("White").into_owned());
        } else if key == b"Black" {
            self.current.black.name = Some(value.decode_utf8().expect("Black").into_owned());
        } else if key == b"WhiteElo" {
            if value.as_bytes() != b"?" {
                self.current.white.rating = Some(btoi::btoi(value.as_bytes()).expect("WhiteElo"));
            }
        } else if key == b"BlackElo" {
            if value.as_bytes() != b"?" {
                self.current.black.rating = Some(btoi::btoi(value.as_bytes()).expect("BlackElo"));
            }
        } else if key == b"TimeControl" {
            self.current.speed = Some(Speed::from_bytes(value.as_bytes()).expect("TimeControl"));
        } else if key == b"Variant" {
            self.current.variant = Some(value.decode_utf8().expect("Variant").into_owned());
        } else if key == b"Date" || key == b"UTCDate" {
            self.current.date = Some(value.decode_utf8().expect("Date").into_owned());
        } else if key == b"WhiteTitle" || key == b"BlackTitle" {
            if value.as_bytes() == b"BOT" {
                self.skip = true;
            }
        } else if key == b"Site" {
            self.current.id = Some(
                String::from_utf8(
                    value
                        .as_bytes()
                        .rsplitn(2, |ch| *ch == b'/')
                        .next()
                        .expect("Site")
                        .to_owned(),
                )
                .expect("Site"),
            );
        } else if key == b"Result" {
            match value.as_bytes() {
                b"1-0" => self.current.winner = Some(Color::White),
                b"0-1" => self.current.winner = Some(Color::Black),
                b"1/2-1/2" => self.current.winner = None,
                _ => self.skip = true,
            }
        } else if key == b"FEN" {
            self.current.fen = Some(value.decode_utf8().expect("FEN").into_owned());
        }
    }

    fn end_headers(&mut self) -> Skip {
        let rating =
            (self.current.white.rating.unwrap_or(0) + self.current.black.rating.unwrap_or(0)) / 2;

        let standard = self
            .current
            .variant
            .as_ref()
            .map_or(false, |name| name != "Standard");

        let probability = if standard {
            match self.current.speed.unwrap_or(Speed::Correspondence) {
                Speed::Correspondence | Speed::Classical => 1.0,

                _ if rating >= 2500 => 1.0,

                Speed::Rapid if rating >= 2200 => 1.0,
                Speed::Rapid if rating >= 2000 => 0.30,
                Speed::Rapid if rating >= 1800 => 0.18,
                Speed::Rapid if rating >= 1600 => 0.16,

                Speed::Blitz if rating >= 2200 => 0.16,
                Speed::Blitz if rating >= 2000 => 0.07,
                Speed::Blitz if rating >= 1800 => 0.05,
                Speed::Blitz if rating >= 1600 => 0.05,

                Speed::Bullet if rating >= 2200 => 0.20,
                Speed::Bullet if rating >= 2000 => 0.11,
                Speed::Bullet if rating >= 1800 => 0.07,
                Speed::Bullet if rating >= 1600 => 0.07,

                Speed::UltraBullet => 1.0,

                _ => 0.02,
            }
        } else {
            // variant games
            if rating >= 1600 {
                1.0
            } else {
                0.5
            }
        };

        let accept = min(
            self.current.white.rating.unwrap_or(0),
            self.current.black.rating.unwrap_or(0),
        ) >= 1501
            && probability >= self.rng.sample(OpenClosed01)
            && !self.skip;

        self.skip = !accept;
        Skip(self.skip)
    }

    fn san(&mut self, san: SanPlus) {
        self.current.moves.push(san);
    }

    fn begin_variation(&mut self) -> Skip {
        Skip(true) // stay in the mainline
    }

    fn end_game(&mut self) {
        if !self.skip {
            self.batch
                .push(mem::replace(&mut self.current, Default::default()));

            if self.batch.len() >= BATCH_SIZE {
                self.send();
            }
        }
    }
}

fn main() -> Result<(), io::Error> {
    for arg in env::args().skip(1) {
        let file = File::open(&arg)?;

        let uncompressed: Box<dyn io::Read> = if arg.ends_with(".bz2") {
            Box::new(bzip2::read::MultiBzDecoder::new(file))
        } else {
            Box::new(file)
        };

        let mut reader = BufferedReader::new(uncompressed);

        let mut importer = Importer::new(arg);
        reader.read_all(&mut importer)?;
    }

    Ok(())
}
<commit_msg>work around ornicar/lichess-db#40<commit_after>use std::{cmp::min, env, fs::File, io, mem, time::Duration};

use pgn_reader::{BufferedReader, Color, RawHeader, SanPlus, Skip, Visitor};
use rand::{distributions::OpenClosed01, rngs::SmallRng, Rng, SeedableRng};
use serde::Serialize;
use serde_with::{serde_as, DisplayFromStr, SpaceSeparator, StringWithSeparator};

const BATCH_SIZE: usize = 50;

#[derive(Debug, Serialize, Copy, Clone)]
#[serde(rename_all = "camelCase")]
enum Speed {
    UltraBullet,
    Bullet,
    Blitz,
    Rapid,
    Classical,
    Correspondence,
}

impl Speed {
    fn from_seconds_and_increment(seconds: u64, increment: u64) -> Speed {
        let total = seconds + 40 * increment;

        if total < 30 {
            Speed::UltraBullet
        } else if total < 180 {
            Speed::Bullet
        } else if total < 480 {
            Speed::Blitz
        } else if total < 1500 {
            Speed::Rapid
        } else if total < 21_600 {
            Speed::Classical
        } else {
            Speed::Correspondence
        }
    }

    fn from_bytes(bytes: &[u8]) -> Result<Speed, ()> {
        if bytes == b"-" {
            return Ok(Speed::Correspondence);
        }

        let mut parts = bytes.splitn(2, |ch| *ch == b'+');
        let seconds = btoi::btou(parts.next().ok_or(())?).map_err(|_| ())?;
        let increment = btoi::btou(parts.next().ok_or(())?).map_err(|_| ())?;
        Ok(Speed::from_seconds_and_increment(seconds, increment))
    }
}

struct Importer {
    filename: String,
    client: reqwest::blocking::Client,
    rng: SmallRng,

    current: Game,
    skip: bool,
    batch: Vec<Game>,
}

#[serde_as]
#[derive(Default, Serialize, Debug)]
struct Game {
    variant: Option<String>,
    speed: Option<Speed>,
    fen: Option<String>,
    id: Option<String>,
    date: Option<String>,
    white: Player,
    black: Player,
    #[serde_as(as = "Option<DisplayFromStr>")]
    winner: Option<Color>,
    #[serde_as(as = "StringWithSeparator<SpaceSeparator, SanPlus>")]
    moves: Vec<SanPlus>,
}

#[derive(Default, Serialize, Debug)]
struct Player {
    name: Option<String>,
    rating: Option<u16>,
}

impl Importer {
    fn new(filename: String) -> Importer {
        Importer {
            filename,
            client: reqwest::blocking::Client::builder()
                .timeout(Duration::from_secs(60))
                .build()
                .expect("client"),
            rng: SmallRng::from_seed([
                0x19, 0x29, 0xab, 0x17, 0xc6, 0xfa, 0xb0, 0xe9, 0x4b, 0x44, 0xd8, 0x07, 0x09, 0xbf,
                0x1d, 0x87, 0xbd, 0xd8, 0xb3, 0x2f, 0xe1, 0xe2, 0xa0, 0x1a, 0x9e, 0x30, 0x98, 0xd7,
                0xef, 0xd5, 0x7a, 0x1d,
            ]),
            current: Game::default(),
            skip: false,
            batch: Vec::with_capacity(BATCH_SIZE),
        }
    }

    pub fn send(&mut self) {
        // println!("{}", serde_json::to_string(&self.batch).expect("serialize"));

        let res = self
            .client
            .put("http://127.0.0.1:9001/import/lichess")
            .json(&self.batch)
            .send()
            .expect("send batch");

        println!(
            "{}: {}: {} - {}",
            self.filename,
            self.batch
                .last()
                .and_then(|g| g.date.as_ref())
                .unwrap_or(&String::new()),
            res.status(),
            res.text().expect("decode response")
        );

        self.batch.clear();
    }
}

impl Visitor for Importer {
    type Result = ();

    fn begin_game(&mut self) {
        self.skip = false;
        self.current = Game::default();
    }

    fn header(&mut self, key: &[u8], value: RawHeader<'_>) {
        if key == b"White" {
            self.current.white.name = Some(value.decode_utf8().expect("White").into_owned());
        } else if key == b"Black" {
            self.current.black.name = Some(value.decode_utf8().expect("Black").into_owned());
        } else if key == b"WhiteElo" {
            if value.as_bytes() != b"?" {
                self.current.white.rating = Some(btoi::btoi(value.as_bytes()).expect("WhiteElo"));
            }
        } else if key == b"BlackElo" {
            if value.as_bytes() != b"?" {
                self.current.black.rating = Some(btoi::btoi(value.as_bytes()).expect("BlackElo"));
            }
        } else if key == b"TimeControl" {
            self.current.speed = Some(Speed::from_bytes(value.as_bytes()).expect("TimeControl"));
        } else if key == b"Variant" {
            self.current.variant = Some(value.decode_utf8().expect("Variant").into_owned());
        } else if key == b"Date" || key == b"UTCDate" {
            self.current.date = Some(value.decode_utf8().expect("Date").into_owned());
        } else if key == b"WhiteTitle" || key == b"BlackTitle" {
            if value.as_bytes() == b"BOT" {
                self.skip = true;
            }
        } else if key == b"Site" {
            self.current.id = Some(
                String::from_utf8(
                    value
                        .as_bytes()
                        .rsplitn(2, |ch| *ch == b'/')
                        .next()
                        .expect("Site")
                        .to_owned(),
                )
                .expect("Site"),
            );
        } else if key == b"Result" {
            match value.as_bytes() {
                b"1-0" => self.current.winner = Some(Color::White),
                b"0-1" => self.current.winner = Some(Color::Black),
                b"1/2-1/2" => self.current.winner = None,
                _ => self.skip = true,
            }
        } else if key == b"FEN" {
            if value.as_bytes() == b"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" {
                // https://github.com/ornicar/lichess-db/issues/40
                self.current.fen = None;
            } else {
                self.current.fen = Some(value.decode_utf8().expect("FEN").into_owned());
            }
        }
    }

    fn end_headers(&mut self) -> Skip {
        let rating =
            (self.current.white.rating.unwrap_or(0) + self.current.black.rating.unwrap_or(0)) / 2;

        let standard = self
            .current
            .variant
            .as_ref()
            .map_or(false, |name| name != "Standard");

        let probability = if standard {
            match self.current.speed.unwrap_or(Speed::Correspondence) {
                Speed::Correspondence | Speed::Classical => 1.0,

                _ if rating >= 2500 => 1.0,

                Speed::Rapid if rating >= 2200 => 1.0,
                Speed::Rapid if rating >= 2000 => 0.30,
                Speed::Rapid if rating >= 1800 => 0.18,
                Speed::Rapid if rating >= 1600 => 0.16,

                Speed::Blitz if rating >= 2200 => 0.16,
                Speed::Blitz if rating >= 2000 => 0.07,
                Speed::Blitz if rating >= 1800 => 0.05,
                Speed::Blitz if rating >= 1600 => 0.05,

                Speed::Bullet if rating >= 2200 => 0.20,
                Speed::Bullet if rating >= 2000 => 0.11,
                Speed::Bullet if rating >= 1800 => 0.07,
                Speed::Bullet if rating >= 1600 => 0.07,

                Speed::UltraBullet => 1.0,

                _ => 0.02,
            }
        } else {
            // variant games
            if rating >= 1600 {
                1.0
            } else {
                0.5
            }
        };

        let accept = min(
            self.current.white.rating.unwrap_or(0),
            self.current.black.rating.unwrap_or(0),
        ) >= 1501
            && probability >= self.rng.sample(OpenClosed01)
            && !self.skip;

        self.skip = !accept;
        Skip(self.skip)
    }

    fn san(&mut self, san: SanPlus) {
        self.current.moves.push(san);
    }

    fn begin_variation(&mut self) -> Skip {
        Skip(true) // stay in the mainline
    }

    fn end_game(&mut self) {
        if !self.skip {
            self.batch
                .push(mem::replace(&mut self.current, Default::default()));

            if self.batch.len() >= BATCH_SIZE {
                self.send();
            }
        }
    }
}

fn main() -> Result<(), io::Error> {
    for arg in env::args().skip(1) {
        let file = File::open(&arg)?;

        let uncompressed: Box<dyn io::Read> = if arg.ends_with(".bz2") {
            Box::new(bzip2::read::MultiBzDecoder::new(file))
        } else {
            Box::new(file)
        };

        let mut reader = BufferedReader::new(uncompressed);

        let mut importer = Importer::new(arg);
        reader.read_all(&mut importer)?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>use super::WinningRootHashSet;
use crate::common::get_attesting_indices_unsorted;
use types::*;

/// Sets the boolean `var` on `self` to be true if it is true on `other`. Otherwise leaves `self`
/// as is.
macro_rules! set_self_if_other_is_true {
    ($self_: ident, $other: ident, $var: ident) => {
        if $other.$var {
            $self_.$var = true;
        }
    };
}

/// The information required to reward some validator for their participation in a "winning"
/// crosslink root.
#[derive(Default, Clone)]
pub struct WinningRootInfo {
    /// The total balance of the crosslink committee.
    pub total_committee_balance: u64,
    /// The total balance of the crosslink committee that attested for the "winning" root.
    pub total_attesting_balance: u64,
}

/// The information required to reward a block producer for including an attestation in a block.
#[derive(Clone, Copy)]
pub struct InclusionInfo {
    /// The earliest slot a validator had an attestation included in the previous epoch.
    pub slot: Slot,
    /// The distance between the attestation slot and the slot that attestation was included in a
    /// block.
    pub distance: u64,
    /// The index of the proposer at the slot where the attestation was included.
    pub proposer_index: usize,
}

impl Default for InclusionInfo {
    /// Defaults to `slot` and `distance` at their maximum values and `proposer_index` at zero.
    fn default() -> Self {
        Self {
            slot: Slot::max_value(),
            distance: u64::max_value(),
            proposer_index: 0,
        }
    }
}

impl InclusionInfo {
    /// Tests if some `other` `InclusionInfo` has a lower inclusion slot than `self`. If so,
    /// replaces `self` with `other`.
    pub fn update(&mut self, other: &Self) {
        if other.slot < self.slot {
            self.slot = other.slot;
            self.distance = other.distance;
            self.proposer_index = other.proposer_index;
        }
    }
}

/// Information required to reward some validator during the current and previous epoch.
#[derive(Default, Clone)]
pub struct ValidatorStatus {
    /// True if the validator has been slashed, ever.
    pub is_slashed: bool,
    /// True if the validator can withdraw in the current epoch.
    pub is_withdrawable_in_current_epoch: bool,
    /// True if the validator was active in the state's _current_ epoch.
    pub is_active_in_current_epoch: bool,
    /// True if the validator was active in the state's _previous_ epoch.
    pub is_active_in_previous_epoch: bool,
    /// The validator's effective balance in the _current_ epoch.
    pub current_epoch_effective_balance: u64,

    /// True if the validator had an attestation included in the _current_ epoch.
    pub is_current_epoch_attester: bool,
    /// True if the validator's beacon block root attestation for the first slot of the _current_
    /// epoch matches the block root known to the state.
    pub is_current_epoch_target_attester: bool,
    /// True if the validator had an attestation included in the _previous_ epoch.
    pub is_previous_epoch_attester: bool,
    /// True if the validator's beacon block root attestation for the first slot of the _previous_
    /// epoch matches the block root known to the state.
    pub is_previous_epoch_target_attester: bool,
    /// True if the validator's beacon block root attestation in the _previous_ epoch at the
    /// attestation's slot (`attestation_data.slot`) matches the block root known to the state.
    pub is_previous_epoch_head_attester: bool,

    /// Information used to reward the block producer of this validators earliest-included
    /// attestation.
    pub inclusion_info: Option<InclusionInfo>,
    /// Information used to reward/penalize the validator if they voted in the super-majority for
    /// some shard block.
    pub winning_root_info: Option<WinningRootInfo>,
}

impl ValidatorStatus {
    /// Accepts some `other` `ValidatorStatus` and updates `self` if required.
    ///
    /// Will never set one of the `bool` fields to `false`, it will only set it to `true` if other
    /// contains a `true` field.
    ///
    /// Note: does not update the winning root info, this is done manually.
    pub fn update(&mut self, other: &Self) {
        // Update all the bool fields, only updating `self` if `other` is true (never setting
        // `self` to false).
        set_self_if_other_is_true!(self, other, is_slashed);
        set_self_if_other_is_true!(self, other, is_withdrawable_in_current_epoch);
        set_self_if_other_is_true!(self, other, is_active_in_current_epoch);
        set_self_if_other_is_true!(self, other, is_active_in_previous_epoch);
        set_self_if_other_is_true!(self, other, is_current_epoch_attester);
        set_self_if_other_is_true!(self, other, is_current_epoch_target_attester);
        set_self_if_other_is_true!(self, other, is_previous_epoch_attester);
        set_self_if_other_is_true!(self, other, is_previous_epoch_target_attester);
        set_self_if_other_is_true!(self, other, is_previous_epoch_head_attester);

        if let Some(other_info) = other.inclusion_info {
            if let Some(self_info) = self.inclusion_info.as_mut() {
                self_info.update(&other_info);
            } else {
                self.inclusion_info = other.inclusion_info;
            }
        }
    }
}

/// The total effective balances for different sets of validators during the previous and current
/// epochs.
#[derive(Default, Clone)]
pub struct TotalBalances {
    /// The total effective balance of all active validators during the _current_ epoch.
    pub current_epoch: u64,
    /// The total effective balance of all active validators during the _previous_ epoch.
    pub previous_epoch: u64,
    /// The total effective balance of all validators who attested during the _current_ epoch.
    pub current_epoch_attesters: u64,
    /// The total effective balance of all validators who attested during the _current_ epoch and
    /// agreed with the state about the beacon block at the first slot of the _current_ epoch.
    pub current_epoch_target_attesters: u64,
    /// The total effective balance of all validators who attested during the _previous_ epoch.
    pub previous_epoch_attesters: u64,
    /// The total effective balance of all validators who attested during the _previous_ epoch and
    /// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
    pub previous_epoch_target_attesters: u64,
    /// The total effective balance of all validators who attested during the _previous_ epoch and
    /// agreed with the state about the beacon block at the time of attestation.
    pub previous_epoch_head_attesters: u64,
}

/// Summarised information about validator participation in the _previous and _current_ epochs of
/// some `BeaconState`.
#[derive(Clone)]
pub struct ValidatorStatuses {
    /// Information about each individual validator from the state's validator registy.
    pub statuses: Vec<ValidatorStatus>,
    /// Summed balances for various sets of validators.
    pub total_balances: TotalBalances,
}

impl ValidatorStatuses {
    /// Initializes a new instance, determining:
    ///
    /// - Active validators
    /// - Total balances for the current and previous epochs.
    ///
    /// Spec v0.6.1
    pub fn new<T: EthSpec>(
        state: &BeaconState<T>,
        spec: &ChainSpec,
    ) -> Result<Self, BeaconStateError> {
        let mut statuses = Vec::with_capacity(state.validator_registry.len());
        let mut total_balances = TotalBalances::default();

        for (i, validator) in state.validator_registry.iter().enumerate() {
            let effective_balance = state.get_effective_balance(i, spec)?;
            let mut status = ValidatorStatus {
                is_slashed: validator.slashed,
                is_withdrawable_in_current_epoch: validator
                    .is_withdrawable_at(state.current_epoch()),
                current_epoch_effective_balance: effective_balance,
                ..ValidatorStatus::default()
            };

            if validator.is_active_at(state.current_epoch()) {
                status.is_active_in_current_epoch = true;
                total_balances.current_epoch += effective_balance;
            }

            if validator.is_active_at(state.previous_epoch()) {
                status.is_active_in_previous_epoch = true;
                total_balances.previous_epoch += effective_balance;
            }

            statuses.push(status);
        }

        Ok(Self {
            statuses,
            total_balances,
        })
    }

    /// Process some attestations from the given `state` updating the `statuses` and
    /// `total_balances` fields.
    ///
    /// Spec v0.6.1
    pub fn process_attestations<T: EthSpec>(
        &mut self,
        state: &BeaconState<T>,
        spec: &ChainSpec,
    ) -> Result<(), BeaconStateError> {
        for a in state
            .previous_epoch_attestations
            .iter()
            .chain(state.current_epoch_attestations.iter())
        {
            let attesting_indices =
                get_attesting_indices_unsorted(state, &a.data, &a.aggregation_bitfield)?;

            let mut status = ValidatorStatus::default();

            // Profile this attestation, updating the total balances and generating an
            // `ValidatorStatus` object that applies to all participants in the attestation.
            if is_from_epoch(a, state.current_epoch()) {
                status.is_current_epoch_attester = true;

                if target_matches_epoch_start_block(a, state, state.current_epoch(), spec)? {
                    status.is_current_epoch_target_attester = true;
                }
            } else if is_from_epoch(a, state.previous_epoch()) {
                status.is_previous_epoch_attester = true;

                // The inclusion slot and distance are only required for previous epoch attesters.
                let attestation_slot = state.get_attestation_slot(&a.data)?;
                let inclusion_slot = attestation_slot + a.inclusion_delay;
                let relative_epoch =
                    RelativeEpoch::from_slot(state.slot, inclusion_slot, spec.slots_per_epoch)?;
                status.inclusion_info = Some(InclusionInfo {
                    slot: inclusion_slot,
                    distance: a.inclusion_delay,
                    proposer_index: state.get_beacon_proposer_index(
                        attestation_slot,
                        relative_epoch,
                        spec,
                    )?,
                });

                if target_matches_epoch_start_block(a, state, state.previous_epoch(), spec)? {
                    status.is_previous_epoch_target_attester = true;
                }

                if has_common_beacon_block_root(a, state)? {
                    status.is_previous_epoch_head_attester = true;
                }
            }

            // Loop through the participating validator indices and update the status vec.
            for validator_index in attesting_indices {
                self.statuses[validator_index].update(&status);
            }
        }

        // Compute the total balances
        for (index, v) in self.statuses.iter().enumerate() {
            // According to the spec, we only count unslashed validators towards the totals.
            if !v.is_slashed {
                let validator_balance = state.get_effective_balance(index, spec)?;

                if v.is_current_epoch_attester {
                    self.total_balances.current_epoch_attesters += validator_balance;
                }
                if v.is_current_epoch_target_attester {
                    self.total_balances.current_epoch_target_attesters += validator_balance;
                }
                if v.is_previous_epoch_attester {
                    self.total_balances.previous_epoch_attesters += validator_balance;
                }
                if v.is_previous_epoch_target_attester {
                    self.total_balances.previous_epoch_target_attesters += validator_balance;
                }
                if v.is_previous_epoch_head_attester {
                    self.total_balances.previous_epoch_head_attesters += validator_balance;
                }
            }
        }

        Ok(())
    }

    /// Update the `statuses` for each validator based upon whether or not they attested to the
    /// "winning" shard block root for the previous epoch.
    ///
    /// Spec v0.6.1
    pub fn process_winning_roots<T: EthSpec>(
        &mut self,
        state: &BeaconState<T>,
        winning_roots: &WinningRootHashSet,
        spec: &ChainSpec,
    ) -> Result<(), BeaconStateError> {
        // Loop through each slot in the previous epoch.
        for slot in state.previous_epoch().slot_iter(spec.slots_per_epoch) {
            let crosslink_committees_at_slot = state.get_crosslink_committees_at_slot(slot)?;

            // Loop through each committee in the slot.
            for c in crosslink_committees_at_slot {
                // If there was some winning crosslink root for the committee's shard.
                if let Some(winning_root) = winning_roots.get(&c.shard) {
                    let total_committee_balance = state.get_total_balance(&c.committee, spec)?;
                    for &validator_index in &winning_root.attesting_validator_indices {
                        // Take note of the balance information for the winning root, it will be
                        // used later to calculate rewards for that validator.
                        self.statuses[validator_index].winning_root_info = Some(WinningRootInfo {
                            total_committee_balance,
                            total_attesting_balance: winning_root.total_attesting_balance,
                        })
                    }
                }
            }
        }

        Ok(())
    }
}

/// Returns `true` if some `PendingAttestation` is from the supplied `epoch`.
///
/// Spec v0.6.1
fn is_from_epoch(a: &PendingAttestation, epoch: Epoch) -> bool {
    a.data.target_epoch == epoch
}

/// Returns `true` if the attestation's FFG target is equal to the hash of the `state`'s first
/// beacon block in the given `epoch`.
///
/// Spec v0.6.1
fn target_matches_epoch_start_block<T: EthSpec>(
    a: &PendingAttestation,
    state: &BeaconState<T>,
    epoch: Epoch,
    spec: &ChainSpec,
) -> Result<bool, BeaconStateError> {
    let slot = epoch.start_slot(spec.slots_per_epoch);
    let state_boundary_root = *state.get_block_root(slot)?;

    Ok(a.data.target_root == state_boundary_root)
}

/// Returns `true` if a `PendingAttestation` and `BeaconState` share the same beacon block hash for
/// the current slot of the `PendingAttestation`.
///
/// Spec v0.6.1
fn has_common_beacon_block_root<T: EthSpec>(
    a: &PendingAttestation,
    state: &BeaconState<T>,
) -> Result<bool, BeaconStateError> {
    let attestation_slot = state.get_attestation_slot(&a.data)?;
    let state_block_root = *state.get_block_root(attestation_slot)?;

    Ok(a.data.beacon_block_root == state_block_root)
}
<commit_msg>epoch processing: fix inclusion info proposer idx<commit_after>use super::WinningRootHashSet;
use crate::common::get_attesting_indices_unsorted;
use types::*;

/// Sets the boolean `var` on `self` to be true if it is true on `other`. Otherwise leaves `self`
/// as is.
macro_rules! set_self_if_other_is_true {
    ($self_: ident, $other: ident, $var: ident) => {
        if $other.$var {
            $self_.$var = true;
        }
    };
}

/// The information required to reward some validator for their participation in a "winning"
/// crosslink root.
#[derive(Default, Clone)]
pub struct WinningRootInfo {
    /// The total balance of the crosslink committee.
    pub total_committee_balance: u64,
    /// The total balance of the crosslink committee that attested for the "winning" root.
    pub total_attesting_balance: u64,
}

/// The information required to reward a block producer for including an attestation in a block.
#[derive(Clone, Copy)]
pub struct InclusionInfo {
    /// The earliest slot a validator had an attestation included in the previous epoch.
    pub slot: Slot,
    /// The distance between the attestation slot and the slot that attestation was included in a
    /// block.
    pub distance: u64,
    /// The index of the proposer at the slot where the attestation was included.
    pub proposer_index: usize,
}

impl Default for InclusionInfo {
    /// Defaults to `slot` and `distance` at their maximum values and `proposer_index` at zero.
    fn default() -> Self {
        Self {
            slot: Slot::max_value(),
            distance: u64::max_value(),
            proposer_index: 0,
        }
    }
}

impl InclusionInfo {
    /// Tests if some `other` `InclusionInfo` has a lower inclusion slot than `self`. If so,
    /// replaces `self` with `other`.
    pub fn update(&mut self, other: &Self) {
        if other.slot < self.slot {
            self.slot = other.slot;
            self.distance = other.distance;
            self.proposer_index = other.proposer_index;
        }
    }
}

/// Information required to reward some validator during the current and previous epoch.
#[derive(Default, Clone)]
pub struct ValidatorStatus {
    /// True if the validator has been slashed, ever.
    pub is_slashed: bool,
    /// True if the validator can withdraw in the current epoch.
    pub is_withdrawable_in_current_epoch: bool,
    /// True if the validator was active in the state's _current_ epoch.
    pub is_active_in_current_epoch: bool,
    /// True if the validator was active in the state's _previous_ epoch.
    pub is_active_in_previous_epoch: bool,
    /// The validator's effective balance in the _current_ epoch.
    pub current_epoch_effective_balance: u64,

    /// True if the validator had an attestation included in the _current_ epoch.
    pub is_current_epoch_attester: bool,
    /// True if the validator's beacon block root attestation for the first slot of the _current_
    /// epoch matches the block root known to the state.
    pub is_current_epoch_target_attester: bool,
    /// True if the validator had an attestation included in the _previous_ epoch.
    pub is_previous_epoch_attester: bool,
    /// True if the validator's beacon block root attestation for the first slot of the _previous_
    /// epoch matches the block root known to the state.
    pub is_previous_epoch_target_attester: bool,
    /// True if the validator's beacon block root attestation in the _previous_ epoch at the
    /// attestation's slot (`attestation_data.slot`) matches the block root known to the state.
    pub is_previous_epoch_head_attester: bool,

    /// Information used to reward the block producer of this validators earliest-included
    /// attestation.
    pub inclusion_info: Option<InclusionInfo>,
    /// Information used to reward/penalize the validator if they voted in the super-majority for
    /// some shard block.
    pub winning_root_info: Option<WinningRootInfo>,
}

impl ValidatorStatus {
    /// Accepts some `other` `ValidatorStatus` and updates `self` if required.
    ///
    /// Will never set one of the `bool` fields to `false`, it will only set it to `true` if other
    /// contains a `true` field.
    ///
    /// Note: does not update the winning root info, this is done manually.
    pub fn update(&mut self, other: &Self) {
        // Update all the bool fields, only updating `self` if `other` is true (never setting
        // `self` to false).
        set_self_if_other_is_true!(self, other, is_slashed);
        set_self_if_other_is_true!(self, other, is_withdrawable_in_current_epoch);
        set_self_if_other_is_true!(self, other, is_active_in_current_epoch);
        set_self_if_other_is_true!(self, other, is_active_in_previous_epoch);
        set_self_if_other_is_true!(self, other, is_current_epoch_attester);
        set_self_if_other_is_true!(self, other, is_current_epoch_target_attester);
        set_self_if_other_is_true!(self, other, is_previous_epoch_attester);
        set_self_if_other_is_true!(self, other, is_previous_epoch_target_attester);
        set_self_if_other_is_true!(self, other, is_previous_epoch_head_attester);

        if let Some(other_info) = other.inclusion_info {
            if let Some(self_info) = self.inclusion_info.as_mut() {
                self_info.update(&other_info);
            } else {
                self.inclusion_info = other.inclusion_info;
            }
        }
    }
}

/// The total effective balances for different sets of validators during the previous and current
/// epochs.
#[derive(Default, Clone)]
pub struct TotalBalances {
    /// The total effective balance of all active validators during the _current_ epoch.
    pub current_epoch: u64,
    /// The total effective balance of all active validators during the _previous_ epoch.
    pub previous_epoch: u64,
    /// The total effective balance of all validators who attested during the _current_ epoch.
    pub current_epoch_attesters: u64,
    /// The total effective balance of all validators who attested during the _current_ epoch and
    /// agreed with the state about the beacon block at the first slot of the _current_ epoch.
    pub current_epoch_target_attesters: u64,
    /// The total effective balance of all validators who attested during the _previous_ epoch.
    pub previous_epoch_attesters: u64,
    /// The total effective balance of all validators who attested during the _previous_ epoch and
    /// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
    pub previous_epoch_target_attesters: u64,
    /// The total effective balance of all validators who attested during the _previous_ epoch and
    /// agreed with the state about the beacon block at the time of attestation.
    pub previous_epoch_head_attesters: u64,
}

/// Summarised information about validator participation in the _previous and _current_ epochs of
/// some `BeaconState`.
#[derive(Clone)]
pub struct ValidatorStatuses {
    /// Information about each individual validator from the state's validator registy.
    pub statuses: Vec<ValidatorStatus>,
    /// Summed balances for various sets of validators.
    pub total_balances: TotalBalances,
}

impl ValidatorStatuses {
    /// Initializes a new instance, determining:
    ///
    /// - Active validators
    /// - Total balances for the current and previous epochs.
    ///
    /// Spec v0.6.1
    pub fn new<T: EthSpec>(
        state: &BeaconState<T>,
        spec: &ChainSpec,
    ) -> Result<Self, BeaconStateError> {
        let mut statuses = Vec::with_capacity(state.validator_registry.len());
        let mut total_balances = TotalBalances::default();

        for (i, validator) in state.validator_registry.iter().enumerate() {
            let effective_balance = state.get_effective_balance(i, spec)?;
            let mut status = ValidatorStatus {
                is_slashed: validator.slashed,
                is_withdrawable_in_current_epoch: validator
                    .is_withdrawable_at(state.current_epoch()),
                current_epoch_effective_balance: effective_balance,
                ..ValidatorStatus::default()
            };

            if validator.is_active_at(state.current_epoch()) {
                status.is_active_in_current_epoch = true;
                total_balances.current_epoch += effective_balance;
            }

            if validator.is_active_at(state.previous_epoch()) {
                status.is_active_in_previous_epoch = true;
                total_balances.previous_epoch += effective_balance;
            }

            statuses.push(status);
        }

        Ok(Self {
            statuses,
            total_balances,
        })
    }

    /// Process some attestations from the given `state` updating the `statuses` and
    /// `total_balances` fields.
    ///
    /// Spec v0.6.1
    pub fn process_attestations<T: EthSpec>(
        &mut self,
        state: &BeaconState<T>,
        spec: &ChainSpec,
    ) -> Result<(), BeaconStateError> {
        for a in state
            .previous_epoch_attestations
            .iter()
            .chain(state.current_epoch_attestations.iter())
        {
            let attesting_indices =
                get_attesting_indices_unsorted(state, &a.data, &a.aggregation_bitfield)?;

            let mut status = ValidatorStatus::default();

            // Profile this attestation, updating the total balances and generating an
            // `ValidatorStatus` object that applies to all participants in the attestation.
            if is_from_epoch(a, state.current_epoch()) {
                status.is_current_epoch_attester = true;

                if target_matches_epoch_start_block(a, state, state.current_epoch(), spec)? {
                    status.is_current_epoch_target_attester = true;
                }
            } else if is_from_epoch(a, state.previous_epoch()) {
                status.is_previous_epoch_attester = true;

                // The inclusion slot and distance are only required for previous epoch attesters.
                let attestation_slot = state.get_attestation_slot(&a.data)?;
                let inclusion_slot = attestation_slot + a.inclusion_delay;
                let relative_epoch =
                    RelativeEpoch::from_slot(state.slot, inclusion_slot, spec.slots_per_epoch)?;
                status.inclusion_info = Some(InclusionInfo {
                    slot: inclusion_slot,
                    distance: a.inclusion_delay,
                    proposer_index: state.get_beacon_proposer_index(
                        inclusion_slot,
                        relative_epoch,
                        spec,
                    )?,
                });

                if target_matches_epoch_start_block(a, state, state.previous_epoch(), spec)? {
                    status.is_previous_epoch_target_attester = true;
                }

                if has_common_beacon_block_root(a, state)? {
                    status.is_previous_epoch_head_attester = true;
                }
            }

            // Loop through the participating validator indices and update the status vec.
            for validator_index in attesting_indices {
                self.statuses[validator_index].update(&status);
            }
        }

        // Compute the total balances
        for (index, v) in self.statuses.iter().enumerate() {
            // According to the spec, we only count unslashed validators towards the totals.
            if !v.is_slashed {
                let validator_balance = state.get_effective_balance(index, spec)?;

                if v.is_current_epoch_attester {
                    self.total_balances.current_epoch_attesters += validator_balance;
                }
                if v.is_current_epoch_target_attester {
                    self.total_balances.current_epoch_target_attesters += validator_balance;
                }
                if v.is_previous_epoch_attester {
                    self.total_balances.previous_epoch_attesters += validator_balance;
                }
                if v.is_previous_epoch_target_attester {
                    self.total_balances.previous_epoch_target_attesters += validator_balance;
                }
                if v.is_previous_epoch_head_attester {
                    self.total_balances.previous_epoch_head_attesters += validator_balance;
                }
            }
        }

        Ok(())
    }

    /// Update the `statuses` for each validator based upon whether or not they attested to the
    /// "winning" shard block root for the previous epoch.
    ///
    /// Spec v0.6.1
    pub fn process_winning_roots<T: EthSpec>(
        &mut self,
        state: &BeaconState<T>,
        winning_roots: &WinningRootHashSet,
        spec: &ChainSpec,
    ) -> Result<(), BeaconStateError> {
        // Loop through each slot in the previous epoch.
        for slot in state.previous_epoch().slot_iter(spec.slots_per_epoch) {
            let crosslink_committees_at_slot = state.get_crosslink_committees_at_slot(slot)?;

            // Loop through each committee in the slot.
            for c in crosslink_committees_at_slot {
                // If there was some winning crosslink root for the committee's shard.
                if let Some(winning_root) = winning_roots.get(&c.shard) {
                    let total_committee_balance = state.get_total_balance(&c.committee, spec)?;
                    for &validator_index in &winning_root.attesting_validator_indices {
                        // Take note of the balance information for the winning root, it will be
                        // used later to calculate rewards for that validator.
                        self.statuses[validator_index].winning_root_info = Some(WinningRootInfo {
                            total_committee_balance,
                            total_attesting_balance: winning_root.total_attesting_balance,
                        })
                    }
                }
            }
        }

        Ok(())
    }
}

/// Returns `true` if some `PendingAttestation` is from the supplied `epoch`.
///
/// Spec v0.6.1
fn is_from_epoch(a: &PendingAttestation, epoch: Epoch) -> bool {
    a.data.target_epoch == epoch
}

/// Returns `true` if the attestation's FFG target is equal to the hash of the `state`'s first
/// beacon block in the given `epoch`.
///
/// Spec v0.6.1
fn target_matches_epoch_start_block<T: EthSpec>(
    a: &PendingAttestation,
    state: &BeaconState<T>,
    epoch: Epoch,
    spec: &ChainSpec,
) -> Result<bool, BeaconStateError> {
    let slot = epoch.start_slot(spec.slots_per_epoch);
    let state_boundary_root = *state.get_block_root(slot)?;

    Ok(a.data.target_root == state_boundary_root)
}

/// Returns `true` if a `PendingAttestation` and `BeaconState` share the same beacon block hash for
/// the current slot of the `PendingAttestation`.
///
/// Spec v0.6.1
fn has_common_beacon_block_root<T: EthSpec>(
    a: &PendingAttestation,
    state: &BeaconState<T>,
) -> Result<bool, BeaconStateError> {
    let attestation_slot = state.get_attestation_slot(&a.data)?;
    let state_block_root = *state.get_block_root(attestation_slot)?;

    Ok(a.data.beacon_block_root == state_block_root)
}
<|endoftext|>


<commit_before>//! Types and traits related to deserializing values from the database

use std::error::Error;
use std::result;

use backend::Backend;
use row::{NamedRow, Row};

/// A specialized result type representing the result of deserializing
/// a value from the database.
pub type Result<T> = result::Result<T, Box<Error + Send + Sync>>;

/// Trait indicating that a record can be queried from the database.
///
/// Types which implement `Queryable` represent the result of a SQL query. This
/// does not necessarily mean they represent a single database table.
///
/// This trait can be derived automatically using `#[derive(Queryable)]`. This
/// trait can only be derived for structs, not enums.
///
/// Diesel represents the return type of a query as a tuple. The purpose of this
/// trait is to convert from a tuple of Rust values that have been deserialized
/// into your struct.
///
/// When this trait is derived, it will assume that the order of fields on your
/// struct match the order of the fields in the query. This means that field
/// order is significant if you are using `#[derive(Queryable)]`. Field name has
/// no affect.
///
/// # Examples
///
/// If we just want to map a query to our struct, we can use `derive`.
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("doctest_setup.rs");
/// #
/// #[derive(Queryable, PartialEq, Debug)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// # fn main() {
/// #     run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let first_user = users.first(&connection)?;
/// let expected = User { id: 1, name: "Sean".into() };
/// assert_eq!(expected, first_user);
/// #     Ok(())
/// # }
/// ```
///
/// If we want to do additional work during deserialization, we can implement
/// the trait ourselves.
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("doctest_setup.rs");
/// #
/// use schema::users;
/// use diesel::deserialize::Queryable;
///
/// # /*
/// type DB = diesel::sqlite::Sqlite;
/// # */
///
/// #[derive(PartialEq, Debug)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// impl Queryable<users::SqlType, DB> for User {
///     type Row = (i32, String);
///
///     fn build(row: Self::Row) -> Self {
///         User {
///             id: row.0,
///             name: row.1.to_lowercase(),
///         }
///     }
/// }
///
/// # fn main() {
/// #     run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let first_user = users.first(&connection)?;
/// let expected = User { id: 1, name: "sean".into() };
/// assert_eq!(expected, first_user);
/// #     Ok(())
/// # }
pub trait Queryable<ST, DB>
where
    DB: Backend,
{
    /// The Rust type you'd like to map from.
    ///
    /// This is typically a tuple of all of your struct's fields.
    type Row: FromSqlRow<ST, DB>;

    /// Construct an instance of this type
    fn build(row: Self::Row) -> Self;
}

// Reasons we can't write this:
//
// impl<T, ST, DB> Queryable<ST, DB> for T
// where
//     DB: Backend,
//     T: FromSqlRow<ST, DB>,
// {
//     type Row = Self;
//
//     fn build(row: Self::Row) -> Self {
//         row
//     }
// }
//
// (this is mostly a reference for @sgrif so he has a better reference every
// time he thinks he has a breakthrough on this problem).
//
// See the comment under `FromSqlRow`. All of the same impls conflict there that
// would here. If we had `#[derive(FromSqlRow)]`, we would also have that
// implement `Queryable`. I know it doesn't look like the `Option` impl
// conflicts, but it definitely does -- It covers types which implement
// `Queryable` but not `FromSqlRow`, while this impl wouldn't.
//
// The same "we could remove one of these traits" applies. Really `FromSqlRow`
// is the only trait that *needs* to exist. At the end of the day, `FromSql` is
// meant to be "I only want to deal with deserializing a single field" case, and
// `Queryable` is meant to be easier to implement by hand than `FromSqlRow`
// would be.

/// Deserializes the result of a query constructed with [`sql_query`].
///
/// # Deriving
///
/// To derive this trait, Diesel needs to know the SQL type of each field. You
/// can do this by either annotating your struct with `#[table_name =
/// "some_table"]` (in which case the SQL type will be
/// `diesel::dsl::SqlTypeOf<table_name::column_name>`), or by annotating each
/// field with `#[sql_type = "SomeType"]`.
///
/// If you are using `#[table_name]`, the module for that table must be in
/// scope. For example, to derive this for a struct called `User`, you will
/// likely need a line such as `use schema::users;`
///
/// If the name of a field on your struct is different than the column in your
/// `table!` declaration, or if you are deriving this trait on a tuple struct,
/// you can annotate the field with `#[column_name = "some_column"]`. For tuple
/// structs, all fields must have this annotation.
///
/// If a field is another struct which implements `QueryableByName`, instead of
/// a column, you can annotate that struct with `#[diesel(embed)]`
///
/// [`sql_query`]: ../fn.sql_query.html
pub trait QueryableByName<DB>
where
    Self: Sized,
    DB: Backend,
{
    /// Construct an instance of `Self` from the database row
    fn build<R: NamedRow<DB>>(row: &R) -> Result<Self>;
}

/// Deserialize a single field of a given SQL type.
///
/// When possible, implementations of this trait should prefer to use an
/// existing implementation, rather than reading from `bytes`. (For example, if
/// you are implementing this for an enum which is represented as an integer in
/// the database, prefer `i32::from_sql(bytes)` over reading from `bytes`
/// directly)
///
/// Types which implement this trait should also have `#[derive(FromSqlRow)]`
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, the actual type of `DB::RawValue` is private API. All
///   implementations of this trait must be written in terms of an existing
///   primitive.
/// - For MySQL, the value of `bytes` will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
pub trait FromSql<A, DB: Backend>: Sized {
    /// See the trait documentation.
    fn from_sql(bytes: Option<&DB::RawValue>) -> Result<Self>;
}

/// Deserialize one or more fields.
///
/// All types which implement `FromSql` should also implement this trait. This
/// trait differs from `FromSql` in that it is also implemented by tuples.
/// Implementations of this trait are usually derived.
///
/// In the future, we hope to be able to provide a blanket impl of this trait
/// for all types which implement `FromSql`. However, as of Diesel 1.0, such an
/// impl would conflict with our impl for tuples.
///
/// ## Deriving
///
/// This trait can be automatically derived by Diesel
/// for any type which implements `FromSql`.
/// There are no options or special considerations needed for this derive.
/// Note that `#[derive(FromSqlRow)]` will also generate a `Queryable` implementation.
pub trait FromSqlRow<A, DB: Backend>: Sized {
    /// The number of fields that this type will consume. Must be equal to
    /// the number of times you would call `row.take()` in `build_from_row`
    const FIELDS_NEEDED: usize = 1;

    /// See the trait documentation.
    fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self>;
}

// Reasons we can't write this:
//
// impl<T, ST, DB> FromSqlRow<ST, DB> for T
// where
//     DB: Backend + HasSqlType<ST>,
//     T: FromSql<ST, DB>,
// {
//     fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self> {
//         Self::from_sql(row.take())
//     }
// }
//
// (this is mostly here so @sgrif has a better reference every time he thinks
// he's somehow had a breakthrough on solving this problem):
//
// - It conflicts with our impl for tuples, because `DB` is a bare type
//   parameter, it could in theory be a local type for some other impl.
//   - This is fixed by replacing our impl with 3 impls, where `DB` is changed
//     concrete backends. This would mean that any third party crates adding new
//     backends would need to add the tuple impls, which sucks but is fine.
// - It conflicts with our impl for `Option`
//   - So we could in theory fix this by both splitting the generic impl into
//     backend specific impls, and removing the `FromSql` impls. In theory there
//     is no reason that it needs to implement `FromSql`, since everything
//     requires `FromSqlRow`, but it really feels like it should.
//   - Specialization might also fix this one. The impl isn't quite a strict
//     subset (the `FromSql` impl has `T: FromSql`, and the `FromSqlRow` impl
//     has `T: FromSqlRow`), but if `FromSql` implies `FromSqlRow`,
//     specialization might consider that a subset?
// - I don't know that we really need it. `#[derive(FromSqlRow)]` is probably
//   good enough. That won't improve our own codebase, since 99% of our
//   `FromSqlRow` impls are for types from another crate, but it's almost
//   certainly good enough for user types.
//   - Still, it really feels like `FromSql` *should* be able to imply both
//   `FromSqlRow` and `Queryable`
<commit_msg>Remove double comment<commit_after>//! Types and traits related to deserializing values from the database

use std::error::Error;
use std::result;

use backend::Backend;
use row::{NamedRow, Row};

/// A specialized result type representing the result of deserializing
/// a value from the database.
pub type Result<T> = result::Result<T, Box<Error + Send + Sync>>;

/// Trait indicating that a record can be queried from the database.
///
/// Types which implement `Queryable` represent the result of a SQL query. This
/// does not necessarily mean they represent a single database table.
///
/// This trait can be derived automatically using `#[derive(Queryable)]`. This
/// trait can only be derived for structs, not enums.
///
/// Diesel represents the return type of a query as a tuple. The purpose of this
/// trait is to convert from a tuple of Rust values that have been deserialized
/// into your struct.
///
/// When this trait is derived, it will assume that the order of fields on your
/// struct match the order of the fields in the query. This means that field
/// order is significant if you are using `#[derive(Queryable)]`. Field name has
/// no affect.
///
/// # Examples
///
/// If we just want to map a query to our struct, we can use `derive`.
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("doctest_setup.rs");
/// #
/// #[derive(Queryable, PartialEq, Debug)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// # fn main() {
/// #     run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let first_user = users.first(&connection)?;
/// let expected = User { id: 1, name: "Sean".into() };
/// assert_eq!(expected, first_user);
/// #     Ok(())
/// # }
/// ```
///
/// If we want to do additional work during deserialization, we can implement
/// the trait ourselves.
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("doctest_setup.rs");
/// #
/// use schema::users;
/// use diesel::deserialize::Queryable;
///
/// # /*
/// type DB = diesel::sqlite::Sqlite;
/// # */
///
/// #[derive(PartialEq, Debug)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// impl Queryable<users::SqlType, DB> for User {
///     type Row = (i32, String);
///
///     fn build(row: Self::Row) -> Self {
///         User {
///             id: row.0,
///             name: row.1.to_lowercase(),
///         }
///     }
/// }
///
/// # fn main() {
/// #     run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let first_user = users.first(&connection)?;
/// let expected = User { id: 1, name: "sean".into() };
/// assert_eq!(expected, first_user);
/// #     Ok(())
/// # }
pub trait Queryable<ST, DB>
where
    DB: Backend,
{
    /// The Rust type you'd like to map from.
    ///
    /// This is typically a tuple of all of your struct's fields.
    type Row: FromSqlRow<ST, DB>;

    /// Construct an instance of this type
    fn build(row: Self::Row) -> Self;
}

/// Deserializes the result of a query constructed with [`sql_query`].
///
/// # Deriving
///
/// To derive this trait, Diesel needs to know the SQL type of each field. You
/// can do this by either annotating your struct with `#[table_name =
/// "some_table"]` (in which case the SQL type will be
/// `diesel::dsl::SqlTypeOf<table_name::column_name>`), or by annotating each
/// field with `#[sql_type = "SomeType"]`.
///
/// If you are using `#[table_name]`, the module for that table must be in
/// scope. For example, to derive this for a struct called `User`, you will
/// likely need a line such as `use schema::users;`
///
/// If the name of a field on your struct is different than the column in your
/// `table!` declaration, or if you are deriving this trait on a tuple struct,
/// you can annotate the field with `#[column_name = "some_column"]`. For tuple
/// structs, all fields must have this annotation.
///
/// If a field is another struct which implements `QueryableByName`, instead of
/// a column, you can annotate that struct with `#[diesel(embed)]`
///
/// [`sql_query`]: ../fn.sql_query.html
pub trait QueryableByName<DB>
where
    Self: Sized,
    DB: Backend,
{
    /// Construct an instance of `Self` from the database row
    fn build<R: NamedRow<DB>>(row: &R) -> Result<Self>;
}

/// Deserialize a single field of a given SQL type.
///
/// When possible, implementations of this trait should prefer to use an
/// existing implementation, rather than reading from `bytes`. (For example, if
/// you are implementing this for an enum which is represented as an integer in
/// the database, prefer `i32::from_sql(bytes)` over reading from `bytes`
/// directly)
///
/// Types which implement this trait should also have `#[derive(FromSqlRow)]`
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, the actual type of `DB::RawValue` is private API. All
///   implementations of this trait must be written in terms of an existing
///   primitive.
/// - For MySQL, the value of `bytes` will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
pub trait FromSql<A, DB: Backend>: Sized {
    /// See the trait documentation.
    fn from_sql(bytes: Option<&DB::RawValue>) -> Result<Self>;
}

/// Deserialize one or more fields.
///
/// All types which implement `FromSql` should also implement this trait. This
/// trait differs from `FromSql` in that it is also implemented by tuples.
/// Implementations of this trait are usually derived.
///
/// In the future, we hope to be able to provide a blanket impl of this trait
/// for all types which implement `FromSql`. However, as of Diesel 1.0, such an
/// impl would conflict with our impl for tuples.
///
/// ## Deriving
///
/// This trait can be automatically derived by Diesel
/// for any type which implements `FromSql`.
/// There are no options or special considerations needed for this derive.
/// Note that `#[derive(FromSqlRow)]` will also generate a `Queryable` implementation.
pub trait FromSqlRow<A, DB: Backend>: Sized {
    /// The number of fields that this type will consume. Must be equal to
    /// the number of times you would call `row.take()` in `build_from_row`
    const FIELDS_NEEDED: usize = 1;

    /// See the trait documentation.
    fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self>;
}

// Reasons we can't write this:
//
// impl<T, ST, DB> FromSqlRow<ST, DB> for T
// where
//     DB: Backend + HasSqlType<ST>,
//     T: FromSql<ST, DB>,
// {
//     fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self> {
//         Self::from_sql(row.take())
//     }
// }
//
// (this is mostly here so @sgrif has a better reference every time he thinks
// he's somehow had a breakthrough on solving this problem):
//
// - It conflicts with our impl for tuples, because `DB` is a bare type
//   parameter, it could in theory be a local type for some other impl.
//   - This is fixed by replacing our impl with 3 impls, where `DB` is changed
//     concrete backends. This would mean that any third party crates adding new
//     backends would need to add the tuple impls, which sucks but is fine.
// - It conflicts with our impl for `Option`
//   - So we could in theory fix this by both splitting the generic impl into
//     backend specific impls, and removing the `FromSql` impls. In theory there
//     is no reason that it needs to implement `FromSql`, since everything
//     requires `FromSqlRow`, but it really feels like it should.
//   - Specialization might also fix this one. The impl isn't quite a strict
//     subset (the `FromSql` impl has `T: FromSql`, and the `FromSqlRow` impl
//     has `T: FromSqlRow`), but if `FromSql` implies `FromSqlRow`,
//     specialization might consider that a subset?
// - I don't know that we really need it. `#[derive(FromSqlRow)]` is probably
//   good enough. That won't improve our own codebase, since 99% of our
//   `FromSqlRow` impls are for types from another crate, but it's almost
//   certainly good enough for user types.
//   - Still, it really feels like `FromSql` *should* be able to imply both
//   `FromSqlRow` and `Queryable`
<|endoftext|>


<commit_before>#![feature(plugin)]
#![warn(clippy::indexing_slicing)]

// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
#![warn(clippy::out_of_bounds_indexing)]
#![allow(clippy::no_effect, clippy::unnecessary_operation)]

fn main() {
    let x = [1, 2, 3, 4];
    let index: usize = 1;
    let index_from: usize = 2;
    let index_to: usize = 3;
    x[index];
    &x[index..];
    &x[..index];
    &x[index_from..index_to];
    &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
    x[4]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
    x[1 << 3]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
    &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10].
    &x[0..][..3];
    &x[1..][..5];

    &x[0..].get(..3); // Ok, should not produce stderr.
    x[0]; // Ok, should not produce stderr.
    x[3]; // Ok, should not produce stderr.
    &x[0..3]; // Ok, should not produce stderr.

    let y = &x;
    y[0];
    &y[1..2];
    &y[0..=4];
    &y[..=4];

    &y[..]; // Ok, should not produce stderr.

    let v = vec![0; 5];
    v[0];
    v[10];
    v[1 << 3];
    &v[10..100];
    &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100].
    &v[10..];
    &v[..100];

    &v[..]; // Ok, should not produce stderr.

    //
    // Continue tests at end function to minimize the changes to this file's corresponding stderr.
    //

    const N: usize = 15; // Out of bounds
    const M: usize = 3; // In bounds
    x[N]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
    x[M]; // Ok, should not produce stderr.
    v[N];
    v[M];
}
<commit_msg>cargo fmt<commit_after>#![feature(plugin)]
#![warn(clippy::indexing_slicing)]
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
#![warn(clippy::out_of_bounds_indexing)]
#![allow(clippy::no_effect, clippy::unnecessary_operation)]

fn main() {
    let x = [1, 2, 3, 4];
    let index: usize = 1;
    let index_from: usize = 2;
    let index_to: usize = 3;
    x[index];
    &x[index..];
    &x[..index];
    &x[index_from..index_to];
    &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
    x[4]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
    x[1 << 3]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
    &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10].
    &x[0..][..3];
    &x[1..][..5];

    &x[0..].get(..3); // Ok, should not produce stderr.
    x[0]; // Ok, should not produce stderr.
    x[3]; // Ok, should not produce stderr.
    &x[0..3]; // Ok, should not produce stderr.

    let y = &x;
    y[0];
    &y[1..2];
    &y[0..=4];
    &y[..=4];

    &y[..]; // Ok, should not produce stderr.

    let v = vec![0; 5];
    v[0];
    v[10];
    v[1 << 3];
    &v[10..100];
    &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100].
    &v[10..];
    &v[..100];

    &v[..]; // Ok, should not produce stderr.

    //
    // Continue tests at end function to minimize the changes to this file's corresponding stderr.
    //

    const N: usize = 15; // Out of bounds
    const M: usize = 3; // In bounds
    x[N]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
    x[M]; // Ok, should not produce stderr.
    v[N];
    v[M];
}
<|endoftext|>


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

use smithay::delegate_compositor;
use smithay::reexports::wayland_server::Display;

use smithay::wayland::compositor::{CompositorHandler, CompositorState};

use wayland_server::backend::{ClientData, ClientId, DisconnectReason};
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{socket::ListeningSocket, DisplayHandle};

struct App {
    compositor_state: CompositorState,
}

impl CompositorHandler for App {
    fn compositor_state(&mut self) -> &mut CompositorState {
        &mut self.compositor_state
    }

    fn commit(&mut self, _dh: &DisplayHandle, surface: &WlSurface) {
        dbg!("Commit", surface);
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut display: Display<App> = Display::new()?;

    let compositor_state = CompositorState::new(&mut display, None);

    let mut state = App { compositor_state };

    let listener = ListeningSocket::bind("wayland-5").unwrap();

    let mut clients = Vec::new();

    loop {
        if let Some(stream) = listener.accept().unwrap() {
            println!("Got a client: {:?}", stream);

            let client = display.insert_client(stream, Arc::new(ClientState)).unwrap();
            clients.push(client);
        }

        display.dispatch_clients(&mut state)?;
        display.flush_clients()?;
    }
}

struct ClientState;
impl ClientData<App> for ClientState {
    fn initialized(&self, _client_id: ClientId) {
        println!("initialized");
    }

    fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) {
        println!("disconnected");
    }
}

impl AsMut<CompositorState> for App {
    fn as_mut(&mut self) -> &mut CompositorState {
        &mut self.compositor_state
    }
}

delegate_compositor!(App);
<commit_msg>compositor-example: fix errors outside of macros<commit_after>use std::sync::Arc;

use smithay::delegate_compositor;
use smithay::reexports::wayland_server::Display;

use smithay::wayland::compositor::{CompositorHandler, CompositorState};

use wayland_server::backend::{ClientData, ClientId, DisconnectReason};
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::{socket::ListeningSocket, DisplayHandle};

struct App {
    compositor_state: CompositorState,
}

impl CompositorHandler for App {
    fn compositor_state(&mut self) -> &mut CompositorState {
        &mut self.compositor_state
    }

    fn commit(&mut self, _dh: &DisplayHandle, surface: &WlSurface) {
        dbg!("Commit", surface);
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut display: Display<App> = Display::new()?;

    let compositor_state = CompositorState::new(&mut display, None);

    let mut state = App { compositor_state };

    let listener = ListeningSocket::bind("wayland-5").unwrap();

    let mut clients = Vec::new();

    loop {
        if let Some(stream) = listener.accept().unwrap() {
            println!("Got a client: {:?}", stream);

            let client = display
                .handle()
                .insert_client(stream, Arc::new(ClientState))
                .unwrap();
            clients.push(client);
        }

        display.dispatch_clients(&mut state)?;
        display.flush_clients()?;
    }
}

struct ClientState;
impl ClientData for ClientState {
    fn initialized(&self, _client_id: ClientId) {
        println!("initialized");
    }

    fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) {
        println!("disconnected");
    }
}

impl AsMut<CompositorState> for App {
    fn as_mut(&mut self) -> &mut CompositorState {
        &mut self.compositor_state
    }
}

delegate_compositor!(App);
<|endoftext|>


<commit_before>// By compiling this file we check that all the intrinsics we care about continue to be provided by
// the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
// compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
// to link due to the missing intrinsic (symbol).

#![allow(unused_features)]
#![cfg_attr(thumb, no_main)]
#![deny(dead_code)]
#![feature(alloc_system)]
#![feature(asm)]
#![feature(compiler_builtins_lib)]
#![feature(core_float)]
#![feature(lang_items)]
#![feature(start)]
#![feature(global_allocator)]
#![feature(allocator_api)]
#![cfg_attr(windows, feature(panic_unwind))]
#![no_core]

extern crate core;

#[cfg(not(thumb))]
extern crate alloc_system;
extern crate compiler_builtins;
#[cfg(windows)]
extern crate panic_unwind;

#[cfg(not(thumb))]
#[global_allocator]
static A: alloc_system::System = alloc_system::System;

// NOTE cfg(not(thumbv6m)) means that the operation is not supported on ARMv6-M at all. Not even
// compiler-rt provides a C/assembly implementation.

// Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
// doesn't have native support for the operation used in the function. ARM has a naming convention
// convention for its intrinsics that's different from other architectures; that's why some function
// have an additional comment: the function name is the ARM name for the intrinsic and the comment
// in the non-ARM name for the intrinsic.
mod intrinsics {
    use core::num::Float;

    // trunccdfsf2
    pub fn aeabi_d2f(x: f64) -> f32 {
        x as f32
    }

    // fixdfsi
    pub fn aeabi_d2i(x: f64) -> i32 {
        x as i32
    }

    // fixdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2l(x: f64) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2l(_: f64) -> i64 {
        0
    }

    // fixunsdfsi
    pub fn aeabi_d2uiz(x: f64) -> u32 {
        x as u32
    }

    // fixunsdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2ulz(x: f64) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2ulz(_: f64) -> u64 {
        0
    }

    // adddf3
    pub fn aeabi_dadd(a: f64, b: f64) -> f64 {
        a + b
    }

    // eqdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpeq(_: f64, _: f64) -> bool {
        true
    }

    // gtdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpgt(_: f64, _: f64) -> bool {
        true
    }

    // ltdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmplt(a: f64, b: f64) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmplt(_: f64, _: f64) -> bool {
        true
    }

    // divdf3
    pub fn aeabi_ddiv(a: f64, b: f64) -> f64 {
        a / b
    }

    // muldf3
    pub fn aeabi_dmul(a: f64, b: f64) -> f64 {
        a * b
    }

    // subdf3
    pub fn aeabi_dsub(a: f64, b: f64) -> f64 {
        a - b
    }

    // extendsfdf2
    pub fn aeabi_f2d(x: f32) -> f64 {
        x as f64
    }

    // fixsfsi
    pub fn aeabi_f2iz(x: f32) -> i32 {
        x as i32
    }

    // fixsfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2lz(x: f32) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2lz(_: f32) -> i64 {
        0
    }

    // fixunssfsi
    pub fn aeabi_f2uiz(x: f32) -> u32 {
        x as u32
    }

    // fixunssfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2ulz(x: f32) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2ulz(_: f32) -> u64 {
        0
    }

    // addsf3
    pub fn aeabi_fadd(a: f32, b: f32) -> f32 {
        a + b
    }

    // eqsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpeq(_: f32, _: f32) -> bool {
        true
    }

    // gtsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpgt(_: f32, _: f32) -> bool {
        true
    }

    // ltsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmplt(a: f32, b: f32) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmplt(_: f32, _: f32) -> bool {
        true
    }

    // divsf3
    pub fn aeabi_fdiv(a: f32, b: f32) -> f32 {
        a / b
    }

    // mulsf3
    pub fn aeabi_fmul(a: f32, b: f32) -> f32 {
        a * b
    }

    // subsf3
    pub fn aeabi_fsub(a: f32, b: f32) -> f32 {
        a - b
    }

    // floatsidf
    pub fn aeabi_i2d(x: i32) -> f64 {
        x as f64
    }

    // floatsisf
    pub fn aeabi_i2f(x: i32) -> f32 {
        x as f32
    }

    pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
        a.wrapping_div(b)
    }

    pub fn aeabi_idivmod(a: i32, b: i32) -> i32 {
        a % b
    }

    // floatdidf
    pub fn aeabi_l2d(x: i64) -> f64 {
        x as f64
    }

    // floatdisf
    pub fn aeabi_l2f(x: i64) -> f32 {
        x as f32
    }

    // divdi3
    pub fn aeabi_ldivmod(a: i64, b: i64) -> i64 {
        a / b
    }

    // muldi3
    pub fn aeabi_lmul(a: i64, b: i64) -> i64 {
        a.wrapping_mul(b)
    }

    // floatunsidf
    pub fn aeabi_ui2d(x: u32) -> f64 {
        x as f64
    }

    // floatunsisf
    pub fn aeabi_ui2f(x: u32) -> f32 {
        x as f32
    }

    pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
        a / b
    }

    pub fn aeabi_uidivmod(a: u32, b: u32) -> u32 {
        a % b
    }

    // floatundidf
    pub fn aeabi_ul2d(x: u64) -> f64 {
        x as f64
    }

    // floatundisf
    pub fn aeabi_ul2f(x: u64) -> f32 {
        x as f32
    }

    // udivdi3
    pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
        a * b
    }

    pub fn moddi3(a: i64, b: i64) -> i64 {
        a % b
    }

    pub fn mulodi4(a: i64, b: i64) -> i64 {
        a * b
    }

    pub fn powidf2(a: f64, b: i32) -> f64 {
        a.powi(b)
    }

    pub fn powisf2(a: f32, b: i32) -> f32 {
        a.powi(b)
    }

    pub fn umoddi3(a: u64, b: u64) -> u64 {
        a % b
    }

    pub fn muloti4(a: u128, b: u128) -> Option<u128> {
        a.checked_mul(b)
    }

    pub fn multi3(a: u128, b: u128) -> u128 {
        a.wrapping_mul(b)
    }

    pub fn ashlti3(a: u128, b: usize) -> u128 {
        a >> b
    }

    pub fn ashrti3(a: u128, b: usize) -> u128 {
        a << b
    }

    pub fn lshrti3(a: i128, b: usize) -> i128 {
        a >> b
    }

    pub fn udivti3(a: u128, b: u128) -> u128 {
        a / b
    }

    pub fn umodti3(a: u128, b: u128) -> u128 {
        a % b
    }

    pub fn divti3(a: i128, b: i128) -> i128 {
        a / b
    }

    pub fn modti3(a: i128, b: i128) -> i128 {
        a % b
    }
}

fn run() {
    use intrinsics::*;

    // A copy of "test::black_box". Used to prevent LLVM from optimizing away the intrinsics during LTO
    fn bb<T>(dummy: T) -> T {
        unsafe { asm!("" : : "r"(&dummy)) }
        dummy
    }

    bb(aeabi_d2f(bb(2.)));
    bb(aeabi_d2i(bb(2.)));
    bb(aeabi_d2l(bb(2.)));
    bb(aeabi_d2uiz(bb(2.)));
    bb(aeabi_d2ulz(bb(2.)));
    bb(aeabi_dadd(bb(2.), bb(3.)));
    bb(aeabi_dcmpeq(bb(2.), bb(3.)));
    bb(aeabi_dcmpgt(bb(2.), bb(3.)));
    bb(aeabi_dcmplt(bb(2.), bb(3.)));
    bb(aeabi_ddiv(bb(2.), bb(3.)));
    bb(aeabi_dmul(bb(2.), bb(3.)));
    bb(aeabi_dsub(bb(2.), bb(3.)));
    bb(aeabi_f2d(bb(2.)));
    bb(aeabi_f2iz(bb(2.)));
    bb(aeabi_f2lz(bb(2.)));
    bb(aeabi_f2uiz(bb(2.)));
    bb(aeabi_f2ulz(bb(2.)));
    bb(aeabi_fadd(bb(2.), bb(3.)));
    bb(aeabi_fcmpeq(bb(2.), bb(3.)));
    bb(aeabi_fcmpgt(bb(2.), bb(3.)));
    bb(aeabi_fcmplt(bb(2.), bb(3.)));
    bb(aeabi_fdiv(bb(2.), bb(3.)));
    bb(aeabi_fmul(bb(2.), bb(3.)));
    bb(aeabi_fsub(bb(2.), bb(3.)));
    bb(aeabi_i2d(bb(2)));
    bb(aeabi_i2f(bb(2)));
    bb(aeabi_idiv(bb(2), bb(3)));
    bb(aeabi_idivmod(bb(2), bb(3)));
    bb(aeabi_l2d(bb(2)));
    bb(aeabi_l2f(bb(2)));
    bb(aeabi_ldivmod(bb(2), bb(3)));
    bb(aeabi_lmul(bb(2), bb(3)));
    bb(aeabi_ui2d(bb(2)));
    bb(aeabi_ui2f(bb(2)));
    bb(aeabi_uidiv(bb(2), bb(3)));
    bb(aeabi_uidivmod(bb(2), bb(3)));
    bb(aeabi_ul2d(bb(2)));
    bb(aeabi_ul2f(bb(2)));
    bb(aeabi_uldivmod(bb(2), bb(3)));
    bb(moddi3(bb(2), bb(3)));
    bb(mulodi4(bb(2), bb(3)));
    bb(powidf2(bb(2.), bb(3)));
    bb(powisf2(bb(2.), bb(3)));
    bb(umoddi3(bb(2), bb(3)));
    bb(muloti4(bb(2), bb(2)));
    bb(multi3(bb(2), bb(2)));
    bb(ashlti3(bb(2), bb(2)));
    bb(ashrti3(bb(2), bb(2)));
    bb(lshrti3(bb(2), bb(2)));
    bb(udivti3(bb(2), bb(2)));
    bb(umodti3(bb(2), bb(2)));
    bb(divti3(bb(2), bb(2)));
    bb(modti3(bb(2), bb(2)));

    something_with_a_dtor(&|| assert_eq!(bb(1), 1));
}

fn something_with_a_dtor(f: &Fn()) {
    struct A<'a>(&'a (Fn() + 'a));

    impl<'a> Drop for A<'a> {
        fn drop(&mut self) {
            (self.0)();
        }
    }
    let _a = A(f);
    f();
}

#[cfg(not(thumb))]
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
    run();
    0
}

#[cfg(thumb)]
#[no_mangle]
pub fn _start() -> ! {
    run();
    loop {}
}

#[cfg(windows)]
#[link(name = "kernel32")]
#[link(name = "msvcrt")]
extern {}

// ARM targets need these symbols
#[no_mangle]
pub fn __aeabi_unwind_cpp_pr0() {}

#[no_mangle]
pub fn __aeabi_unwind_cpp_pr1() {}

#[cfg(not(windows))]
#[allow(non_snake_case)]
#[no_mangle]
pub fn _Unwind_Resume() {}

#[cfg(not(windows))]
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn eh_personality() {}

#[lang = "panic_fmt"]
#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn panic_fmt() {}
<commit_msg>More attempts for intrinsics example<commit_after>// By compiling this file we check that all the intrinsics we care about continue to be provided by
// the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
// compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
// to link due to the missing intrinsic (symbol).

#![allow(unused_features)]
#![cfg_attr(thumb, no_main)]
#![deny(dead_code)]
#![feature(alloc_system)]
#![feature(asm)]
#![feature(compiler_builtins_lib)]
#![feature(core_float)]
#![feature(lang_items)]
#![feature(start)]
#![feature(global_allocator)]
#![feature(allocator_api)]
#![cfg_attr(windows, feature(panic_unwind))]
#![no_std]

#[cfg(not(thumb))]
#[link(name = "c")]
extern {}

// NOTE cfg(not(thumbv6m)) means that the operation is not supported on ARMv6-M at all. Not even
// compiler-rt provides a C/assembly implementation.

// Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
// doesn't have native support for the operation used in the function. ARM has a naming convention
// convention for its intrinsics that's different from other architectures; that's why some function
// have an additional comment: the function name is the ARM name for the intrinsic and the comment
// in the non-ARM name for the intrinsic.
mod intrinsics {
    // trunccdfsf2
    pub fn aeabi_d2f(x: f64) -> f32 {
        x as f32
    }

    // fixdfsi
    pub fn aeabi_d2i(x: f64) -> i32 {
        x as i32
    }

    // fixdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2l(x: f64) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2l(_: f64) -> i64 {
        0
    }

    // fixunsdfsi
    pub fn aeabi_d2uiz(x: f64) -> u32 {
        x as u32
    }

    // fixunsdfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_d2ulz(x: f64) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_d2ulz(_: f64) -> u64 {
        0
    }

    // adddf3
    pub fn aeabi_dadd(a: f64, b: f64) -> f64 {
        a + b
    }

    // eqdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpeq(_: f64, _: f64) -> bool {
        true
    }

    // gtdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmpgt(_: f64, _: f64) -> bool {
        true
    }

    // ltdf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_dcmplt(a: f64, b: f64) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_dcmplt(_: f64, _: f64) -> bool {
        true
    }

    // divdf3
    pub fn aeabi_ddiv(a: f64, b: f64) -> f64 {
        a / b
    }

    // muldf3
    pub fn aeabi_dmul(a: f64, b: f64) -> f64 {
        a * b
    }

    // subdf3
    pub fn aeabi_dsub(a: f64, b: f64) -> f64 {
        a - b
    }

    // extendsfdf2
    pub fn aeabi_f2d(x: f32) -> f64 {
        x as f64
    }

    // fixsfsi
    pub fn aeabi_f2iz(x: f32) -> i32 {
        x as i32
    }

    // fixsfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2lz(x: f32) -> i64 {
        x as i64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2lz(_: f32) -> i64 {
        0
    }

    // fixunssfsi
    pub fn aeabi_f2uiz(x: f32) -> u32 {
        x as u32
    }

    // fixunssfdi
    #[cfg(not(thumbv6m))]
    pub fn aeabi_f2ulz(x: f32) -> u64 {
        x as u64
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_f2ulz(_: f32) -> u64 {
        0
    }

    // addsf3
    pub fn aeabi_fadd(a: f32, b: f32) -> f32 {
        a + b
    }

    // eqsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool {
        a == b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpeq(_: f32, _: f32) -> bool {
        true
    }

    // gtsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool {
        a > b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmpgt(_: f32, _: f32) -> bool {
        true
    }

    // ltsf2
    #[cfg(not(thumbv6m))]
    pub fn aeabi_fcmplt(a: f32, b: f32) -> bool {
        a < b
    }

    #[cfg(thumbv6m)]
    pub fn aeabi_fcmplt(_: f32, _: f32) -> bool {
        true
    }

    // divsf3
    pub fn aeabi_fdiv(a: f32, b: f32) -> f32 {
        a / b
    }

    // mulsf3
    pub fn aeabi_fmul(a: f32, b: f32) -> f32 {
        a * b
    }

    // subsf3
    pub fn aeabi_fsub(a: f32, b: f32) -> f32 {
        a - b
    }

    // floatsidf
    pub fn aeabi_i2d(x: i32) -> f64 {
        x as f64
    }

    // floatsisf
    pub fn aeabi_i2f(x: i32) -> f32 {
        x as f32
    }

    pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
        a.wrapping_div(b)
    }

    pub fn aeabi_idivmod(a: i32, b: i32) -> i32 {
        a % b
    }

    // floatdidf
    pub fn aeabi_l2d(x: i64) -> f64 {
        x as f64
    }

    // floatdisf
    pub fn aeabi_l2f(x: i64) -> f32 {
        x as f32
    }

    // divdi3
    pub fn aeabi_ldivmod(a: i64, b: i64) -> i64 {
        a / b
    }

    // muldi3
    pub fn aeabi_lmul(a: i64, b: i64) -> i64 {
        a.wrapping_mul(b)
    }

    // floatunsidf
    pub fn aeabi_ui2d(x: u32) -> f64 {
        x as f64
    }

    // floatunsisf
    pub fn aeabi_ui2f(x: u32) -> f32 {
        x as f32
    }

    pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
        a / b
    }

    pub fn aeabi_uidivmod(a: u32, b: u32) -> u32 {
        a % b
    }

    // floatundidf
    pub fn aeabi_ul2d(x: u64) -> f64 {
        x as f64
    }

    // floatundisf
    pub fn aeabi_ul2f(x: u64) -> f32 {
        x as f32
    }

    // udivdi3
    pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
        a * b
    }

    pub fn moddi3(a: i64, b: i64) -> i64 {
        a % b
    }

    pub fn mulodi4(a: i64, b: i64) -> i64 {
        a * b
    }

    pub fn umoddi3(a: u64, b: u64) -> u64 {
        a % b
    }

    pub fn muloti4(a: u128, b: u128) -> Option<u128> {
        a.checked_mul(b)
    }

    pub fn multi3(a: u128, b: u128) -> u128 {
        a.wrapping_mul(b)
    }

    pub fn ashlti3(a: u128, b: usize) -> u128 {
        a >> b
    }

    pub fn ashrti3(a: u128, b: usize) -> u128 {
        a << b
    }

    pub fn lshrti3(a: i128, b: usize) -> i128 {
        a >> b
    }

    pub fn udivti3(a: u128, b: u128) -> u128 {
        a / b
    }

    pub fn umodti3(a: u128, b: u128) -> u128 {
        a % b
    }

    pub fn divti3(a: i128, b: i128) -> i128 {
        a / b
    }

    pub fn modti3(a: i128, b: i128) -> i128 {
        a % b
    }
}

fn run() {
    use intrinsics::*;

    // A copy of "test::black_box". Used to prevent LLVM from optimizing away the intrinsics during LTO
    fn bb<T>(dummy: T) -> T {
        unsafe { asm!("" : : "r"(&dummy)) }
        dummy
    }

    bb(aeabi_d2f(bb(2.)));
    bb(aeabi_d2i(bb(2.)));
    bb(aeabi_d2l(bb(2.)));
    bb(aeabi_d2uiz(bb(2.)));
    bb(aeabi_d2ulz(bb(2.)));
    bb(aeabi_dadd(bb(2.), bb(3.)));
    bb(aeabi_dcmpeq(bb(2.), bb(3.)));
    bb(aeabi_dcmpgt(bb(2.), bb(3.)));
    bb(aeabi_dcmplt(bb(2.), bb(3.)));
    bb(aeabi_ddiv(bb(2.), bb(3.)));
    bb(aeabi_dmul(bb(2.), bb(3.)));
    bb(aeabi_dsub(bb(2.), bb(3.)));
    bb(aeabi_f2d(bb(2.)));
    bb(aeabi_f2iz(bb(2.)));
    bb(aeabi_f2lz(bb(2.)));
    bb(aeabi_f2uiz(bb(2.)));
    bb(aeabi_f2ulz(bb(2.)));
    bb(aeabi_fadd(bb(2.), bb(3.)));
    bb(aeabi_fcmpeq(bb(2.), bb(3.)));
    bb(aeabi_fcmpgt(bb(2.), bb(3.)));
    bb(aeabi_fcmplt(bb(2.), bb(3.)));
    bb(aeabi_fdiv(bb(2.), bb(3.)));
    bb(aeabi_fmul(bb(2.), bb(3.)));
    bb(aeabi_fsub(bb(2.), bb(3.)));
    bb(aeabi_i2d(bb(2)));
    bb(aeabi_i2f(bb(2)));
    bb(aeabi_idiv(bb(2), bb(3)));
    bb(aeabi_idivmod(bb(2), bb(3)));
    bb(aeabi_l2d(bb(2)));
    bb(aeabi_l2f(bb(2)));
    bb(aeabi_ldivmod(bb(2), bb(3)));
    bb(aeabi_lmul(bb(2), bb(3)));
    bb(aeabi_ui2d(bb(2)));
    bb(aeabi_ui2f(bb(2)));
    bb(aeabi_uidiv(bb(2), bb(3)));
    bb(aeabi_uidivmod(bb(2), bb(3)));
    bb(aeabi_ul2d(bb(2)));
    bb(aeabi_ul2f(bb(2)));
    bb(aeabi_uldivmod(bb(2), bb(3)));
    bb(moddi3(bb(2), bb(3)));
    bb(mulodi4(bb(2), bb(3)));
    bb(umoddi3(bb(2), bb(3)));
    bb(muloti4(bb(2), bb(2)));
    bb(multi3(bb(2), bb(2)));
    bb(ashlti3(bb(2), bb(2)));
    bb(ashrti3(bb(2), bb(2)));
    bb(lshrti3(bb(2), bb(2)));
    bb(udivti3(bb(2), bb(2)));
    bb(umodti3(bb(2), bb(2)));
    bb(divti3(bb(2), bb(2)));
    bb(modti3(bb(2), bb(2)));

    something_with_a_dtor(&|| assert_eq!(bb(1), 1));
}

fn something_with_a_dtor(f: &Fn()) {
    struct A<'a>(&'a (Fn() + 'a));

    impl<'a> Drop for A<'a> {
        fn drop(&mut self) {
            (self.0)();
        }
    }
    let _a = A(f);
    f();
}

#[cfg(not(thumb))]
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
    run();
    0
}

#[cfg(thumb)]
#[no_mangle]
pub fn _start() -> ! {
    run();
    loop {}
}

#[cfg(windows)]
#[link(name = "kernel32")]
#[link(name = "msvcrt")]
extern {}

// ARM targets need these symbols
#[no_mangle]
pub fn __aeabi_unwind_cpp_pr0() {}

#[no_mangle]
pub fn __aeabi_unwind_cpp_pr1() {}

#[cfg(not(windows))]
#[allow(non_snake_case)]
#[no_mangle]
pub fn _Unwind_Resume() {}

#[cfg(not(windows))]
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn eh_personality() {}

#[lang = "panic_fmt"]
#[no_mangle]
#[allow(private_no_mangle_fns)]
extern "C" fn panic_fmt() {}
<|endoftext|>


<commit_before>use syntect::easy::HighlightLines;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{ThemeSet,Style};
use syntect::util::{as_latex_escaped,LinesWithEndings};

fn main() {
    // Load these once at the start of your program
    let ps = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();

    let syntax = ps.find_syntax_by_extension("rs").unwrap();
    let s = "pub struct Wow { hi: u64 }\nfn blah() -> u64 {}\n";

    let mut h = HighlightLines::new(syntax, &ts.themes["InspiredGitHub"]);
    for line in LinesWithEndings::from(s) { // LinesWithEndings enables use of newlines mode
        let ranges: Vec<(Style, &str)> = h.highlight(line, &ps);
        let escaped = as_latex_escaped(&ranges[..]);
        println!("\n{:?}", line);
        println!("\n{}", escaped);
    }
}
<commit_msg>remove stray whitespace<commit_after>use syntect::easy::HighlightLines;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{ThemeSet,Style};
use syntect::util::{as_latex_escaped,LinesWithEndings};

fn main() {
    // Load these once at the start of your program
    let ps = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();

    let syntax = ps.find_syntax_by_extension("rs").unwrap();
    let s = "pub struct Wow { hi: u64 }\nfn blah() -> u64 {}\n";

    let mut h = HighlightLines::new(syntax, &ts.themes["InspiredGitHub"]);
    for line in LinesWithEndings::from(s) { // LinesWithEndings enables use of newlines mode
        let ranges: Vec<(Style, &str)> = h.highlight(line, &ps);
        let escaped = as_latex_escaped(&ranges[..]);
        println!("\n{:?}", line);
        println!("\n{}", escaped);
    }
}
<|endoftext|>