<commit_before>//! Handling of DICOM values with the PN (person name) value representation
//! as per PS3.5 sect 6.2.
use std::fmt::{Display, Formatter};

/// A DICOM _Person Name_ (PN value representation).
///
/// Values of this type keep
/// family name, given name, middle name, prefix and suffix
/// as borrowed values.
/// All name components are optional.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PersonName<'a> {
    prefix: Option<&'a str>,
    family: Option<&'a str>,
    middle: Option<&'a str>,
    given: Option<&'a str>,
    suffix: Option<&'a str>,
}

/// A builder to construct a [`PersonName`] from its components.
#[derive(Debug, Copy, Clone)]
pub struct PersonNameBuilder<'a> {
    person_name: PersonName<'a>,
}

impl Display for PersonName<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let components: &[Option<&str>] = &[
            self.prefix,
            self.given,
            self.middle,
            self.family,
            self.suffix,
        ];

        let mut c_iter = components.iter().flatten().peekable();

        while let Some(component) = c_iter.next() {
            if c_iter.peek().is_some() {
                write!(f, "{} ", component)?
            } else {
                write!(f, "{}", component)?
            }
        }
        Ok(())
    }
}

impl<'a> PersonName<'a> {
    /// Retrieve PersonName prefix
    pub fn prefix(&self) -> Option<&str> {
        self.prefix
    }
    /// Retrieve PersonName suffix
    pub fn suffix(&self) -> Option<&str> {
        self.suffix
    }
    /// Retrieve family name from PersonName
    pub fn family(&self) -> Option<&str> {
        self.family
    }
    /// Retrieve given name from PersonName
    pub fn given(&self) -> Option<&str> {
        self.given
    }
    /// Retrieve middle name from PersonName
    pub fn middle(&self) -> Option<&str> {
        self.middle
    }
    /// Convert the person name into a DICOM formatted string.
    ///
    /// Name components are interspersed with a `'^'` separator.
    /// Leading null components produce a separator,
    /// while trailing components do not.
    pub fn to_dicom_string(&self) -> String {
        let mut name = String::new();

        let components: &[Option<&str>] = &[
            self.family,
            self.given,
            self.middle,
            self.prefix,
            self.suffix,
        ];

        let mut it  = components.iter().rev().peekable();
        // consume trailing None (null) components
        while it.next_if(|component| component.is_none()).is_some(){}

        let mut it = it.rev().peekable();
        while let Some(option) = it.next() {
            if let Some(component) = option {
                name.push_str(component);
            }
            if it.peek().is_some() {
                name.push('^');
            }
        }

        name
    }
    /// Retrieves a PersonName from a Dicom formatted string slice.
    /// The Dicom string representation is split by '^' separator into its respective components.
    pub fn from_slice(slice: &'a str) -> PersonName<'a> {
        let mut parts = slice.split('^');

        macro_rules! get_component {
            () => {
                parts
                    .next()
                    .and_then(|s| if s.is_empty() { None } else { Some(s) })
            };
        }

        let family = get_component!();
        let given = get_component!();
        let middle = get_component!();
        let prefix = get_component!();
        let suffix = get_component!();

        PersonName {
            prefix,
            given,
            family,
            middle,
            suffix,
        }
    }
    /// Retrieve a builder for a PersonName
    pub fn builder() -> PersonNameBuilder<'a> {
        PersonNameBuilder::new()
    }
}

impl<'a> PersonNameBuilder<'a> {
    pub fn new() -> PersonNameBuilder<'a> {
        PersonNameBuilder {
            person_name: PersonName {
                prefix: None,
                family: None,
                middle: None,
                given: None,
                suffix: None,
            },
        }
    }

    /// Insert or update the family name component.
    pub fn with_family(mut self, family_name: &'a str) -> Self {
        self.person_name.family = Some(family_name);
        self
    }

    /// Insert or update the middle name component.
    pub fn with_middle(mut self, middle_name: &'a str) -> Self {
        self.person_name.middle = Some(middle_name);
        self
    }

    /// Insert or update the given name component.
    pub fn with_given(mut self, given_name: &'a str) -> Self {
        self.person_name.given = Some(given_name);
        self
    }

    /// Insert or update the prefix component.
    pub fn with_prefix(mut self, name_prefix: &'a str) -> Self {
        self.person_name.prefix = Some(name_prefix);
        self
    }

    /// Insert or update the suffix component.
    pub fn with_suffix(mut self, name_suffix: &'a str) -> Self {
        self.person_name.suffix = Some(name_suffix);
        self
    }

    /// Builds the person name with the accumulated components.
    pub fn build(&self) -> PersonName<'a> {
        self.person_name
    }
}

impl<'a> Default for PersonNameBuilder<'a> {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_person_name_to_dicom_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_dicom_string(), "^^^^B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^Rev.^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^Robert".to_string());
    }
    #[test]
    fn test_person_name_to_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Adams".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev.".to_string());

        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_string(),
            "Rev. John Robert Adams B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "John Robert Adams B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev. John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Robert".to_string());
    }
    #[test]
    fn person_name_from_slice() {
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^Rev."),
            PersonName {
                prefix: Some("Rev."),
                given: None,
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: None,
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^John"),
            PersonName {
                prefix: None,
                given: Some("John"),
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams"),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^Robert^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^John^Robert^Rev.^B.A. M.Div."),
            PersonName {
                prefix: Some("Rev."),
                given: Some("John"),
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
    }
}
<commit_msg>[core] Make PersonNameBuilder non-consuming<commit_after>//! Handling of DICOM values with the PN (person name) value representation
//! as per PS3.5 sect 6.2.
use std::fmt::{Display, Formatter};

/// A DICOM _Person Name_ (PN value representation).
///
/// Values of this type keep
/// family name, given name, middle name, prefix and suffix
/// as borrowed values.
/// All name components are optional.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PersonName<'a> {
    prefix: Option<&'a str>,
    family: Option<&'a str>,
    middle: Option<&'a str>,
    given: Option<&'a str>,
    suffix: Option<&'a str>,
}

/// A builder to construct a [`PersonName`] from its components.
#[derive(Debug, Copy, Clone)]
pub struct PersonNameBuilder<'a> {
    person_name: PersonName<'a>,
}

impl Display for PersonName<'_> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let components: &[Option<&str>] = &[
            self.prefix,
            self.given,
            self.middle,
            self.family,
            self.suffix,
        ];

        let mut c_iter = components.iter().flatten().peekable();

        while let Some(component) = c_iter.next() {
            if c_iter.peek().is_some() {
                write!(f, "{} ", component)?
            } else {
                write!(f, "{}", component)?
            }
        }
        Ok(())
    }
}

impl<'a> PersonName<'a> {
    /// Retrieve PersonName prefix
    pub fn prefix(&self) -> Option<&str> {
        self.prefix
    }
    /// Retrieve PersonName suffix
    pub fn suffix(&self) -> Option<&str> {
        self.suffix
    }
    /// Retrieve family name from PersonName
    pub fn family(&self) -> Option<&str> {
        self.family
    }
    /// Retrieve given name from PersonName
    pub fn given(&self) -> Option<&str> {
        self.given
    }
    /// Retrieve middle name from PersonName
    pub fn middle(&self) -> Option<&str> {
        self.middle
    }
    /// Convert the person name into a DICOM formatted string.
    ///
    /// Name components are interspersed with a `'^'` separator.
    /// Leading null components produce a separator,
    /// while trailing components do not.
    pub fn to_dicom_string(&self) -> String {
        let mut name = String::new();

        let components: &[Option<&str>] = &[
            self.family,
            self.given,
            self.middle,
            self.prefix,
            self.suffix,
        ];

        let mut it  = components.iter().rev().peekable();
        // consume trailing None (null) components
        while it.next_if(|component| component.is_none()).is_some(){}

        let mut it = it.rev().peekable();
        while let Some(option) = it.next() {
            if let Some(component) = option {
                name.push_str(component);
            }
            if it.peek().is_some() {
                name.push('^');
            }
        }

        name
    }
    /// Retrieves a PersonName from a Dicom formatted string slice.
    /// The Dicom string representation is split by '^' separator into its respective components.
    pub fn from_slice(slice: &'a str) -> PersonName<'a> {
        let mut parts = slice.split('^');

        macro_rules! get_component {
            () => {
                parts
                    .next()
                    .and_then(|s| if s.is_empty() { None } else { Some(s) })
            };
        }

        let family = get_component!();
        let given = get_component!();
        let middle = get_component!();
        let prefix = get_component!();
        let suffix = get_component!();

        PersonName {
            prefix,
            given,
            family,
            middle,
            suffix,
        }
    }
    /// Retrieve a builder for a PersonName
    pub fn builder() -> PersonNameBuilder<'a> {
        PersonNameBuilder::new()
    }
}

impl<'a> PersonNameBuilder<'a> {
    pub fn new() -> PersonNameBuilder<'a> {
        PersonNameBuilder {
            person_name: PersonName {
                prefix: None,
                family: None,
                middle: None,
                given: None,
                suffix: None,
            },
        }
    }

    /// Insert or update the family name component.
    pub fn with_family(&mut self, family_name: &'a str) -> &mut Self {
        self.person_name.family = Some(family_name);
        self
    }

    /// Insert or update the middle name component.
    pub fn with_middle(&mut self, middle_name: &'a str) -> &mut Self {
        self.person_name.middle = Some(middle_name);
        self
    }

    /// Insert or update the given name component.
    pub fn with_given(&mut self, given_name: &'a str) -> &mut Self {
        self.person_name.given = Some(given_name);
        self
    }

    /// Insert or update the prefix component.
    pub fn with_prefix(&mut self, name_prefix: &'a str) -> &mut Self {
        self.person_name.prefix = Some(name_prefix);
        self
    }

    /// Insert or update the suffix component.
    pub fn with_suffix(&mut self, name_suffix: &'a str) -> &mut Self {
        self.person_name.suffix = Some(name_suffix);
        self
    }

    /// Builds the person name with the accumulated components.
    pub fn build(&self) -> PersonName<'a> {
        self.person_name
    }
}

impl<'a> Default for PersonNameBuilder<'a> {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_person_name_to_dicom_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_dicom_string(), "^^^^B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^Rev.^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_dicom_string(),
            "Adams^John^Robert^^B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert^Rev.".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "Adams^John^Robert".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_dicom_string(), "^^Robert".to_string());
    }
    #[test]
    fn test_person_name_to_string() {
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: None,
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Adams".to_string());

        let p = PersonName {
            prefix: Some("Rev."),
            given: None,
            middle: None,
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev.".to_string());

        let p = PersonName {
            prefix: None,
            given: None,
            middle: None,
            family: None,
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(
            p.to_string(),
            "Rev. John Robert Adams B.A. M.Div.".to_string()
        );
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: Some("B.A. M.Div."),
        };
        assert_eq!(p.to_string(), "John Robert Adams B.A. M.Div.".to_string());
        let p = PersonName {
            prefix: Some("Rev."),
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "Rev. John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: Some("John"),
            middle: Some("Robert"),
            family: Some("Adams"),
            suffix: None,
        };
        assert_eq!(p.to_string(), "John Robert Adams".to_string());
        let p = PersonName {
            prefix: None,
            given: None,
            middle: Some("Robert"),
            family: None,
            suffix: None,
        };
        assert_eq!(p.to_string(), "Robert".to_string());
    }
    #[test]
    fn person_name_from_slice() {
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^Rev."),
            PersonName {
                prefix: Some("Rev."),
                given: None,
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: None,
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("^^Robert"),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("^John"),
            PersonName {
                prefix: None,
                given: Some("John"),
                middle: None,
                family: None,
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams"),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: None,
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: None,
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^^Robert^^B.A. M.Div."),
            PersonName {
                prefix: None,
                given: None,
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
        assert_eq!(
            PersonName::from_slice("Adams^John^Robert^Rev.^B.A. M.Div."),
            PersonName {
                prefix: Some("Rev."),
                given: Some("John"),
                middle: Some("Robert"),
                family: Some("Adams"),
                suffix: Some("B.A. M.Div."),
            }
        );
    }
}
<|endoftext|>


<commit_before>/// Kempston key type. Port bit encoded in enum values
pub enum KempstonKey {
    Right = 0x01,
    Left = 0x02,
    Down = 0x04,
    Up = 0x08,
    Fire = 0x10,
}

/// Kempston Joystick
#[derive(Default)]
pub(crate) struct KempstonJoy {
    state: u8,
}

impl KempstonJoy {
    /// Simulates key press/release
    pub fn key(&mut self, key: KempstonKey, state: bool) {
        if state {
            self.state |= key as u8;
        } else {
            self.state &= !(key as u8);
        }
    }

    /// Reads joy value
    pub fn read(&self) -> u8 {
        self.state
    }
}
<commit_msg>Added support for additional Kempston joy butons<commit_after>/// Kempston key type. Port bit encoded in enum values
pub enum KempstonKey {
    Right = 0x01,
    Left = 0x02,
    Down = 0x04,
    Up = 0x08,
    Fire = 0x10,
    /// Undocumented extra button 1
    Ext1 = 0x20,
    /// Undocumented extra button 2
    Ext2 = 0x40,
    /// Undocumented extra button 3
    Ext3 = 0x80,
}

/// Kempston Joystick
#[derive(Default)]
pub(crate) struct KempstonJoy {
    state: u8,
}

impl KempstonJoy {
    /// Simulates key press/release
    pub fn key(&mut self, key: KempstonKey, state: bool) {
        if state {
            self.state |= key as u8;
        } else {
            self.state &= !(key as u8);
        }
    }

    /// Reads joy value
    pub fn read(&self) -> u8 {
        self.state
    }
}
<|endoftext|>


<commit_before>extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate libimagstore;
extern crate libimagrt;
extern crate libimagentrytag;
extern crate libimagerror;

use std::process::exit;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagentrytag::tagable::Tagable;
use libimagentrytag::tag::Tag;
use libimagstore::storeid::build_entry_path;
use libimagerror::trace::{trace_error, trace_error_exit};
use libimagentrytag::ui::{get_add_tags, get_remove_tags};

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup("imag-store",
                                    &version!()[..],
                                    "Direct interface to the store. Use with great care!",
                                    build_ui);

    let id = rt.cli().value_of("id").unwrap(); // enforced by clap
    rt.cli()
        .subcommand_name()
        .map_or_else(
            || {
                let add = get_add_tags(rt.cli());
                let rem = get_remove_tags(rt.cli());
                alter(&rt, id, add, rem);
            },
            |name| {
                debug!("Call: {}", name);
                match name {
                    "list" => list(id, &rt),
                    _ => {
                        warn!("Unknown command");
                        // More error handling
                    },
                };
            });
}

fn alter(rt: &Runtime, id: &str, add: Option<Vec<Tag>>, rem: Option<Vec<Tag>>) {
    let path = {
        match build_entry_path(rt.store(), id) {
            Err(e) => trace_error_exit(&e, 1),
            Ok(s) => s,
        }
    };
    debug!("path = {:?}", path);

    match rt.store().get(path) {
        Ok(Some(mut e)) => {
            add.map(|tags| {
                for tag in tags {
                    debug!("Adding tag '{:?}'", tag);
                    if let Err(e) = e.add_tag(tag) {
                        trace_error(&e);
                    }
                }
            }); // it is okay to ignore a None here

            rem.map(|tags| {
                for tag in tags {
                    debug!("Removing tag '{:?}'", tag);
                    if let Err(e) = e.remove_tag(tag) {
                        trace_error(&e);
                    }
                }
            }); // it is okay to ignore a None here
        },

        Ok(None) => {
            info!("No entry found.");
        },

        Err(e) => {
            info!("No entry.");
            trace_error(&e);
        },
    }
}

fn list(id: &str, rt: &Runtime) {
    let path = {
        match build_entry_path(rt.store(), id) {
            Err(e) => trace_error_exit(&e, 1),
            Ok(s) => s,
        }
    };
    debug!("path = {:?}", path);

    let entry = match rt.store().get(path.clone()) {
        Ok(Some(e)) => e,
        Ok(None) => {
            info!("No entry found.");
            exit(1);
        },

        Err(e) => {
            debug!("Could not get '{:?}' => {:?}", id, path);
            warn!("Could not get entry '{}'", id);
            trace_error_exit(&e, 1);
        },
    };

    let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe, we checked in main()

    let json_out = scmd.is_present("json");
    let line_out = scmd.is_present("linewise");
    let sepp_out = scmd.is_present("sep");
    let mut comm_out = scmd.is_present("commasep");

    if !vec![json_out, line_out, comm_out, sepp_out].iter().any(|v| *v) {
        // None of the flags passed, go to default
        comm_out = true;
    }

    let tags = entry.get_tags();
    if tags.is_err() {
        trace_error_exit(&tags.unwrap_err(), 1);
    }
    let tags = tags.unwrap();

    if json_out {
        unimplemented!()
    }

    if line_out {
        for tag in &tags {
            println!("{}", tag);
        }
    }

    if sepp_out {
        let sepp = scmd.value_of("sep").unwrap(); // we checked before
        println!("{}", tags.join(sepp));
    }

    if comm_out {
        println!("{}", tags.join(", "));
    }
}

<commit_msg>Fix imag-tag::* for new StoreId interface<commit_after>extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate libimagstore;
extern crate libimagrt;
extern crate libimagentrytag;
extern crate libimagerror;

use std::process::exit;
use std::path::PathBuf;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagentrytag::tagable::Tagable;
use libimagentrytag::tag::Tag;
use libimagerror::trace::{trace_error, trace_error_exit};
use libimagentrytag::ui::{get_add_tags, get_remove_tags};
use libimagstore::storeid::StoreId;

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup("imag-store",
                                    &version!()[..],
                                    "Direct interface to the store. Use with great care!",
                                    build_ui);

    let id = rt.cli().value_of("id").unwrap(); // enforced by clap
    rt.cli()
        .subcommand_name()
        .map_or_else(
            || {
                let id = PathBuf::from(id);
                let add = get_add_tags(rt.cli());
                let rem = get_remove_tags(rt.cli());
                alter(&rt, id, add, rem);
            },
            |name| {
                let id = PathBuf::from(id);
                debug!("Call: {}", name);
                match name {
                    "list" => list(id, &rt),
                    _ => {
                        warn!("Unknown command");
                        // More error handling
                    },
                };
            });
}

fn alter(rt: &Runtime, id: PathBuf, add: Option<Vec<Tag>>, rem: Option<Vec<Tag>>) {
    let path = {
        match StoreId::new(Some(rt.store().path().clone()), id) {
            Err(e) => trace_error_exit(&e, 1),
            Ok(s) => s,
        }
    };
    debug!("path = {:?}", path);

    match rt.store().get(path) {
        Ok(Some(mut e)) => {
            add.map(|tags| {
                for tag in tags {
                    debug!("Adding tag '{:?}'", tag);
                    if let Err(e) = e.add_tag(tag) {
                        trace_error(&e);
                    }
                }
            }); // it is okay to ignore a None here

            rem.map(|tags| {
                for tag in tags {
                    debug!("Removing tag '{:?}'", tag);
                    if let Err(e) = e.remove_tag(tag) {
                        trace_error(&e);
                    }
                }
            }); // it is okay to ignore a None here
        },

        Ok(None) => {
            info!("No entry found.");
        },

        Err(e) => {
            info!("No entry.");
            trace_error(&e);
        },
    }
}

fn list(id: PathBuf, rt: &Runtime) {
    let path = match StoreId::new(Some(rt.store().path().clone()), id) {
        Err(e) => trace_error_exit(&e, 1),
        Ok(s)  => s,
    };
    debug!("path = {:?}", path);

    let entry = match rt.store().get(path.clone()) {
        Ok(Some(e)) => e,
        Ok(None) => {
            info!("No entry found.");
            exit(1);
        },

        Err(e) => {
            warn!("Could not get entry '{:?}'", path);
            trace_error_exit(&e, 1);
        },
    };

    let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe, we checked in main()

    let json_out = scmd.is_present("json");
    let line_out = scmd.is_present("linewise");
    let sepp_out = scmd.is_present("sep");
    let mut comm_out = scmd.is_present("commasep");

    if !vec![json_out, line_out, comm_out, sepp_out].iter().any(|v| *v) {
        // None of the flags passed, go to default
        comm_out = true;
    }

    let tags = entry.get_tags();
    if tags.is_err() {
        trace_error_exit(&tags.unwrap_err(), 1);
    }
    let tags = tags.unwrap();

    if json_out {
        unimplemented!()
    }

    if line_out {
        for tag in &tags {
            println!("{}", tag);
        }
    }

    if sepp_out {
        let sepp = scmd.value_of("sep").unwrap(); // we checked before
        println!("{}", tags.join(sepp));
    }

    if comm_out {
        println!("{}", tags.join(", "));
    }
}

<|endoftext|>


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

// Basic test for liveness constraints: the region (`R1`) that appears
// in the type of `p` includes the points after `&v[0]` up to (but not
// including) the call to `use_x`. The `else` branch is not included.

// compile-flags:-Zborrowck=compare -Znll -Ztwo-phase-borrows

#![allow(warnings)]
#![feature(rustc_attrs)]

struct MyStruct {
    field: String
}

fn foo1() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR (Ast) [E0502]
    }
}

fn foo2() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR (Ast) [E0502]
        //~| ERROR (Mir) [E0502]
    }
    drop(value);
}

fn main() { }
<commit_msg>Remove added two-phase-borrows flag<commit_after>// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Basic test for liveness constraints: the region (`R1`) that appears
// in the type of `p` includes the points after `&v[0]` up to (but not
// including) the call to `use_x`. The `else` branch is not included.

// compile-flags:-Zborrowck=compare -Znll

#![allow(warnings)]
#![feature(rustc_attrs)]

struct MyStruct {
    field: String
}

fn foo1() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR (Ast) [E0502]
    }
}

fn foo2() {
    let mut my_struct = MyStruct { field: format!("Hello") };

    let value = &my_struct.field;
    if value.is_empty() {
        my_struct.field.push_str("Hello, world!");
        //~^ ERROR (Ast) [E0502]
        //~| ERROR (Mir) [E0502]
    }
    drop(value);
}

fn main() { }
<|endoftext|>


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

/// Contains helpers for build.rs files.  Includes helpers for proto compilation
use std::path::{Path, PathBuf};

use walkdir::WalkDir;

// Compiles all proto files under proto root and dependent roots.
// For example, if there is a file `src/a/b/c.proto`, it will generate `src/a/b/c.rs` and
// `src/a/b/c_grpc.rs`.
pub fn compile_proto(proto_root: &str, dependent_roots: Vec<&str>, generate_client_code: bool) {
    let mut additional_includes = vec![];
    for dependent_root in dependent_roots {
        // First compile dependent directories
        compile_dir(
            &dependent_root,
            vec![], /* additional_includes */
            false,  /* generate_client_code */
        );
        additional_includes.push(Path::new(dependent_root).to_path_buf());
    }
    // Now compile this directory
    compile_dir(&proto_root, additional_includes, generate_client_code);
}

// Compile all of the proto files in proto_root directory and use the additional
// includes when compiling.
pub fn compile_dir(
    proto_root: &str,
    additional_includes: Vec<PathBuf>,
    generate_client_code: bool,
) {
    for entry in WalkDir::new(proto_root) {
        let p = entry.unwrap();
        if p.file_type().is_dir() {
            continue;
        }

        let path = p.path();
        if let Some(ext) = path.extension() {
            if ext != "proto" {
                continue;
            }
            println!("cargo:rerun-if-changed={}", path.display());
            compile(&path, &additional_includes, generate_client_code);
        }
    }
}

fn compile(path: &Path, additional_includes: &[PathBuf], generate_client_code: bool) {
    let parent = path.parent().unwrap();
    let mut src_path = parent.to_owned().to_path_buf();
    src_path.push("src");

    let mut includes = additional_includes.to_owned();
    includes.push(parent.to_path_buf());

    ::protoc_grpcio::compile_grpc_protos(&[path], includes.as_slice(), parent)
        .unwrap_or_else(|_| panic!("Failed to compile protobuf input: {:?}", path));

    if generate_client_code {
        let file_string = path
            .file_name()
            .expect("unable to get filename")
            .to_str()
            .unwrap();
        let includes_strings = includes
            .iter()
            .map(|x| x.to_str().unwrap())
            .collect::<Vec<&str>>();

        // generate client code
        grpcio_client::client_stub_gen(
            &[file_string],
            includes_strings.as_slice(),
            &parent.to_str().unwrap(),
        )
        .expect("Unable to generate client stub");
    }
}
<commit_msg>Unset go modules support so protobuf can be built<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

/// Contains helpers for build.rs files.  Includes helpers for proto compilation
use std::path::{Path, PathBuf};

use std::env;
use walkdir::WalkDir;

// Compiles all proto files under proto root and dependent roots.
// For example, if there is a file `src/a/b/c.proto`, it will generate `src/a/b/c.rs` and
// `src/a/b/c_grpc.rs`.
pub fn compile_proto(proto_root: &str, dependent_roots: Vec<&str>, generate_client_code: bool) {
    let mut additional_includes = vec![];
    env::remove_var("GO111MODULE");
    for dependent_root in dependent_roots {
        // First compile dependent directories
        compile_dir(
            &dependent_root,
            vec![], /* additional_includes */
            false,  /* generate_client_code */
        );
        additional_includes.push(Path::new(dependent_root).to_path_buf());
    }
    // Now compile this directory
    compile_dir(&proto_root, additional_includes, generate_client_code);
}

// Compile all of the proto files in proto_root directory and use the additional
// includes when compiling.
pub fn compile_dir(
    proto_root: &str,
    additional_includes: Vec<PathBuf>,
    generate_client_code: bool,
) {
    for entry in WalkDir::new(proto_root) {
        let p = entry.unwrap();
        if p.file_type().is_dir() {
            continue;
        }

        let path = p.path();
        if let Some(ext) = path.extension() {
            if ext != "proto" {
                continue;
            }
            println!("cargo:rerun-if-changed={}", path.display());
            compile(&path, &additional_includes, generate_client_code);
        }
    }
}

fn compile(path: &Path, additional_includes: &[PathBuf], generate_client_code: bool) {
    let parent = path.parent().unwrap();
    let mut src_path = parent.to_owned().to_path_buf();
    src_path.push("src");

    let mut includes = additional_includes.to_owned();
    includes.push(parent.to_path_buf());

    ::protoc_grpcio::compile_grpc_protos(&[path], includes.as_slice(), parent)
        .unwrap_or_else(|_| panic!("Failed to compile protobuf input: {:?}", path));

    if generate_client_code {
        let file_string = path
            .file_name()
            .expect("unable to get filename")
            .to_str()
            .unwrap();
        let includes_strings = includes
            .iter()
            .map(|x| x.to_str().unwrap())
            .collect::<Vec<&str>>();

        // generate client code
        grpcio_client::client_stub_gen(
            &[file_string],
            includes_strings.as_slice(),
            &parent.to_str().unwrap(),
        )
        .expect("Unable to generate client stub");
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

pub trait PerfLogger: Send + Sync {
    type PerfLogEvent: PerfLogEvent + Send;
    /// Create log event
    fn create_event(&self, name: impl Copy + Into<String>) -> Self::PerfLogEvent;

    /// Push event to the logger queue
    fn complete_event(&self, event: Self::PerfLogEvent);

    /// Flush all log events
    fn flush(&self);
}

pub trait PerfLogEvent {
    type Timer;

    /// Log number
    fn number(&self, name: impl Copy + Into<String>, number: usize);

    /// Provides a possibility to log additional fields describing current run (like, project name)
    fn string(&self, name: impl Copy + Into<String>, value: String);

    /// Start new execution timer with the name
    fn start(&self, name: impl Copy + Into<String>) -> Self::Timer;

    /// Stop timer and log execution time
    fn stop(&self, timer: Self::Timer);

    /// Measure a time of calling a callback.
    fn time<T, F>(&self, name: impl Copy + Into<String>, f: F) -> T
    where
        F: FnOnce() -> T,
    {
        let timer = self.start(name);
        let res = f();
        self.stop(timer);
        res
    }
}
<commit_msg>Make perf logger thread safe<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

pub trait PerfLogger: Send + Sync {
    type PerfLogEvent: PerfLogEvent + Send;
    /// Create log event
    fn create_event(&self, name: impl Copy + Into<String>) -> Self::PerfLogEvent;

    /// Push event to the logger queue
    fn complete_event(&self, event: Self::PerfLogEvent);

    /// Flush all log events
    fn flush(&self);
}

pub trait PerfLogEvent: Send + Sync {
    type Timer: Send + Sync;

    /// Log number
    fn number(&self, name: impl Copy + Into<String>, number: usize);

    /// Provides a possibility to log additional fields describing current run (like, project name)
    fn string(&self, name: impl Copy + Into<String>, value: String);

    /// Start new execution timer with the name
    fn start(&self, name: impl Copy + Into<String>) -> Self::Timer;

    /// Stop timer and log execution time
    fn stop(&self, timer: Self::Timer);

    /// Measure a time of calling a callback.
    fn time<T, F>(&self, name: impl Copy + Into<String>, f: F) -> T
    where
        F: FnOnce() -> T,
    {
        let timer = self.start(name);
        let res = f();
        self.stop(timer);
        res
    }
}
<|endoftext|>


<commit_before>// ! Spit string with a delimeter.

// xxx

pub( crate ) mod internal
{

  /* xxx : qqq : tab after git sync */

use former::Former;
// use woptions::*; /* xxx : use prelude */

///
/// Either delimeter or delimeted with the slice on its string.
///

#[allow(dead_code)]
#[ derive( Debug ) ]
pub struct Split< 'a >
{
  string : &'a str,
  typ : SplitType,
}

impl< 'a > From< Split< 'a > > for String
{
  fn from( src : Split ) -> Self
  {
    src.string.into()
  }
}

///
/// Either delimeter or delimeted
///

#[ derive( Debug ) ]
pub enum SplitType
{
  /// Substring of the original string with text inbetween delimeters.
  Delimeted,
  /// Delimeter.
  Delimeter,
}

///
/// Split iterator.
///

#[ derive( Debug ) ]
pub struct SplitIterator< 'a >
{
  iterator : std::iter::Peekable< std::str::Split< 'a, &'a str > >,
  counter : i32,
  delimeter : &'a str,
  preserving_empty : bool,
  preserving_delimeters : bool,
  stripping : bool,
}

//

impl< 'a > SplitIterator< 'a >
{
  fn new
  (
    src : &'a str,
    delimeter : &'a str,
    preserving_empty : bool,
    preserving_delimeters : bool,
    stripping : bool
  ) -> Self
  {
    let counter = 0;
    // let delimeter = delimeter.clone();
    let delimeter_slice = unsafe
    {
      let slice = core::slice::from_raw_parts( delimeter.as_ptr(), delimeter.len() );
      core::str::from_utf8_unchecked( slice )
    };
    let iterator = src.split( delimeter_slice ).peekable();
    Self
    {
      iterator,
      delimeter,
      counter,
      preserving_empty,
      preserving_delimeters,
      stripping,
    }
  }
}

//

impl< 'a > Iterator for SplitIterator< 'a >
{
  type Item = Split< 'a >;

  fn next( &mut self ) -> Option< Self::Item >
  {
    self.counter += 1;

    if self.counter % 2 == 1
    {
      let next = self.iterator.next();
      if let Some( mut next ) = next
      {
        if self.stripping
        {
          next = next.trim();
        }

        Some( Split { string : next, typ : SplitType::Delimeted } )
      }
      else
      {
        None
      }
    }
    else
    {
      if self.iterator.peek().is_none()
      {
        self.iterator.next();
        return None;
      }

      let mut string = self.delimeter;

      if self.stripping
      {
        string = string.trim();

        if string.is_empty() && !self.preserving_empty
        {
          string = self.iterator.next().unwrap().trim();
          return Some( Split { string, typ : SplitType::Delimeted } );
        }
      }

      if self.preserving_delimeters
      {
        return Some( Split { string, typ : SplitType::Delimeter } );
      }
      else
      {
        string = self.iterator.next().unwrap();
        if self.stripping
        {
          string = string.trim();
        }
        return Some( Split { string, typ : SplitType::Delimeted } );
      }
    }
  }
}

///
/// Options of function split.
///

#[ derive( Debug ) ]
#[ derive( Former ) ]
#[ perform( fn split( self ) -> SplitIterator< 'a > ) ]
pub struct SplitOptions< 'a >
{

  #[ default( "" ) ]
  src : &'a str,
  #[ default( "" ) ]
  delimeter : &'a str,
  #[ default( true ) ]
  preserving_empty : bool,
  #[ default( true ) ]
  preserving_delimeters : bool,
  #[ default( true ) ]
  stripping : bool,

  // #[ method ]
  // fn split( self ) -> SplitIterator< 'a >
  // where
  //   Self : Sized,
  // {
  //   SplitIterator::new( self.src(), self.delimeter() )
  // }

  // result : HashMap< Box< str >, Box< str > >,
}

///
/// Adapter for Split Options.
///

pub trait SplitOptionsAdapter< 'a >
{
  /// A string to split.
  fn src( &self ) -> &'a str;
  /// A delimeter to split string.
  fn delimeter( &self ) -> &'a str;
  /// Preserving or dropping empty splits.
  fn preserving_empty( &self ) -> bool;
  /// Preserving or dropping delimeters.
  fn preserving_delimeters( &self ) -> bool;
  /// Stripping.
  fn stripping( &self ) -> bool;
  /// Do splitting.
  fn split( self ) -> SplitIterator< 'a >
  where
    Self : Sized,
  {
    SplitIterator::new
    (
      self.src(),
      self.delimeter(),
      self.preserving_empty(),
      self.preserving_delimeters(),
      self.stripping()
    )
  }
}

//

impl< 'a > SplitOptionsAdapter< 'a > for SplitOptions< 'a >
{
  fn src( &self ) -> &'a str
  {
    self.src
  }
  fn delimeter( &self ) -> &'a str
  {
    self.delimeter
  }
  fn preserving_empty( &self ) -> bool
  {
    self.preserving_empty
  }
  fn preserving_delimeters( &self ) -> bool
  {
    self.preserving_delimeters
  }
  fn stripping( &self ) -> bool
  {
    self.stripping
  }
}

///
/// Function to split a string.
///
/// It produces former. To convert former into options and run algorithm of splitting call `form()`.
///
/// # Sample
/// ```
///   let iter = wstring_tools::string::split()
///   .src( "abc def" )
///   .delimeter( " " )
///   .perform();
/// ```

pub fn split< 'a >() -> SplitOptionsFormer< 'a >
{
  SplitOptions::former()
}

}

/// Owned namespace of the module.
pub mod own
{
  use super::internal as i;

  pub use i::Split;
  pub use i::SplitType;
  pub use i::SplitIterator;
  pub use i::SplitOptions;
  pub use i::SplitOptionsAdapter;
  pub use i::split;
}

pub use own::*;

/// Exposed namespace of the module.
pub mod exposed
{
  use super::internal as i;

  pub use i::SplitOptionsAdapter;
  pub use i::split;
}

/// Namespace of the module to include with `use module::*`.
pub mod prelude
{
  use super::internal as i;

  pub use i::SplitOptionsAdapter;
}
<commit_msg>Improve module `split`, use parametric delimeter, reimplement builder manually<commit_after>// ! Spit string with a delimeter.

// xxx

pub( crate ) mod internal
{

  /* xxx : qqq : tab after git sync */

// use woptions::*; /* xxx : use prelude */

///
/// Either delimeter or delimeted with the slice on its string.
///

#[allow(dead_code)]
#[ derive( Debug ) ]
pub struct Split< 'a >
{
  string : &'a str,
  typ : SplitType,
}

impl< 'a > From< Split< 'a > > for String
{
  fn from( src : Split ) -> Self
  {
    src.string.into()
  }
}

///
/// Either delimeter or delimeted
///

#[ derive( Debug ) ]
pub enum SplitType
{
  /// Substring of the original string with text inbetween delimeters.
  Delimeted,
  /// Delimeter.
  Delimeter,
}

///
/// Find first match in the string.
///

pub trait Searcher
{
  /// Find positions of delimeter.
  fn pos( &self, src : &str ) -> Option< ( usize, usize ) >;
}

impl Searcher for &str
{
  fn pos( &self, src : &str ) -> Option< ( usize, usize ) >
  {
    src.find( self ).map( | start | ( start, start + self.len() ) )
  }
}

///
/// Split iterator.
///

#[ derive( Debug ) ]
pub struct SplitIterator< 'a, D >
where
  D : Searcher
{
  iterable : &'a str,
  counter : i32,
  delimeter : D,
  preserving_empty : bool,
  preserving_delimeters : bool,
  stripping : bool,
  stop_empty : bool,
}

//

impl< 'a, D : Searcher > SplitIterator< 'a, D >
{
  fn new
  (
    src : &'a str,
    delimeter : D,
    preserving_empty : bool,
    preserving_delimeters : bool,
    stripping : bool
  ) -> Self
  {
    Self
    {
      iterable : src,
      delimeter,
      counter : 0,
      preserving_empty,
      preserving_delimeters,
      stripping,
      stop_empty : false,
    }
  }
}

//

impl< 'a, D > Iterator for SplitIterator< 'a, D >
where
  D : Searcher
{
  type Item = Split< 'a >;

  fn next( &mut self ) -> Option< Self::Item >
  {
    self.counter += 1;

    if self.counter % 2 == 1
    {
      let positions = self.delimeter.pos( self.iterable );
      if let Some( ( mut start, end ) ) = positions
      {
        if self.iterable == "" && start == end
        {
          if self.stop_empty
          {
            return None;
          }
          else
          {
            self.counter -= 1;
            self.stop_empty = true;
            return Some( Split { string : "", typ : SplitType::Delimeted } );
          }
        }
        let mut next = &self.iterable[ ..start ];
        if start == end
        {
          if self.counter >= 3
          {
            next = &self.iterable[ ..start+1 ];
            start += 1;
          }
        }
        if self.stripping
        {
          next = next.trim();
        }

        self.iterable = &self.iterable[ start.. ];

        Some( Split { string : next, typ : SplitType::Delimeted } )
      }
      else
      {
        return self.next_end_split();
      }
    }
    else
    {
      if self.delimeter.pos( self.iterable ).is_none()
      {
        self.iterable = "";
        return None;
      }

      let ( start, end ) = self.delimeter.pos( self.iterable ).unwrap();
      let mut string = &self.iterable[ start..end ];
      self.iterable = &self.iterable[ end.. ];

      if self.stripping
      {
        string = string.trim();

        if string.is_empty() && !self.preserving_empty
        {
          return self.next_odd_split();
        }
      }

      if self.preserving_delimeters
      {
        return Some( Split { string, typ : SplitType::Delimeter } );
      }
      else
      {
        return self.next_odd_split();
      }
    }
  }
}

impl< 'a, D > SplitIterator< 'a, D >
where
  D : Searcher
{
  fn next_end_split( &mut self ) -> Option< Split< 'a > >
  {
    if self.iterable == ""
    {
      return None;
    }
    else
    {
      let mut string = self.iterable;
      if self.stripping
      {
        string = string.trim();
      }
      let r = Split { string, typ : SplitType::Delimeted };
      self.iterable = "";
      return Some( r );
    }
  }

  fn next_odd_split( &mut self ) -> Option< Split< 'a > >
  {
    match self.delimeter.pos( self.iterable )
    {
      Some( ( start, mut end ) ) =>
      {
        let mut string = &self.iterable[ ..start ];

        if start == end
        {
          string = &self.iterable[ ..start+1 ];
          end += 1;
        }
        self.iterable = &self.iterable[ end.. ];
        if self.stripping
        {
          string = string.trim();
        }
        return Some( Split { string, typ : SplitType::Delimeted } );
      },
      None =>
      {
        self.next_end_split()
      },
    }
  }
}

///
/// Options of function split.
///

#[ derive( Debug ) ]
pub struct SplitOptions< 'a, D >
where
  D : Searcher + Default + Clone
{
  src : &'a str,
  delimeter : D,
  preserving_empty : bool,
  preserving_delimeters : bool,
  stripping : bool,
}

//

macro_rules! builder_impls_from
{
  ( $name : ident, $( ( $field : ident, $type : ty ) ),* $( , )? ) =>
  {
    impl< 'a, D > $name< 'a, D >
    where
      D : Searcher + Default + Clone
    {
      $(
        pub fn $field( mut self, value : $type ) -> $name< 'a, D >
        {
          assert!( !self.formed, "Already formed" );
          self.$field = value;
          self
        }
      )*

      pub fn form( mut self ) -> $name< 'a, D >
      {
        assert!( !self.formed, "Already formed" );
        self.formed = true;
        self
      }
    }
  }
}

/// Builder.
#[ derive( Debug ) ]
pub struct SplitOptionsBuilder< 'a, D >
where
  D : Searcher + Default + Clone
{

  src : &'a str,
  delimeter : D,
  preserving_empty : bool,
  preserving_delimeters : bool,
  stripping : bool,
  formed : bool,
}
builder_impls_from!( SplitOptionsBuilder, ( src, &'a str ), ( preserving_empty, bool ), ( preserving_delimeters, bool ), ( stripping, bool ) );

impl< 'a, D > SplitOptionsBuilder< 'a, D >
where
  D : Searcher + Default + Clone
{
  pub fn new( delimeter : D ) -> SplitOptionsBuilder< 'a, D >
  {
    Self
    {
      src : "",
      delimeter,
      preserving_empty : true,
      preserving_delimeters : true,
      stripping : true,
      formed : false,
    }
  }

  pub fn delimeter( mut self, value : D ) -> SplitOptionsBuilder< 'a, D >
  {
    assert!( !self.formed, "Already formed" );
    self.delimeter = value;
    self
  }

  pub fn perform( &self ) -> SplitIterator< 'a, D >
  {
    let opts = SplitOptions
    {
      src : self.src,
      delimeter : self.delimeter.clone(),
      preserving_empty : self.preserving_empty,
      preserving_delimeters : self.preserving_delimeters,
      stripping : self.stripping,
    };
    opts.split()
  }
}

///
/// Adapter for Split Options.
///

pub trait SplitOptionsAdapter< 'a, D >
{
  /// A string to split.
  fn src( &self ) -> &'a str;
  /// A delimeter to split string.
  fn delimeter( &self ) -> D;
  /// Preserving or dropping empty splits.
  fn preserving_empty( &self ) -> bool;
  /// Preserving or dropping delimeters.
  fn preserving_delimeters( &self ) -> bool;
  /// Stripping.
  fn stripping( &self ) -> bool;
  /// Do splitting.
  fn split( self ) -> SplitIterator< 'a, D >
  where
    Self : Sized,
    D : Searcher + Default,
  {
    SplitIterator::new
    (
      self.src(),
      self.delimeter(),
      self.preserving_empty(),
      self.preserving_delimeters(),
      self.stripping()
    )
  }
}

//

impl< 'a, D > SplitOptionsAdapter< 'a, D > for SplitOptions< 'a, D >
where
  D : Searcher + Default + Clone,
{
  fn src( &self ) -> &'a str
  {
    self.src
  }
  fn delimeter( &self ) -> D
  {
    self.delimeter.clone()
  }
  fn preserving_empty( &self ) -> bool
  {
    self.preserving_empty
  }
  fn preserving_delimeters( &self ) -> bool
  {
    self.preserving_delimeters
  }
  fn stripping( &self ) -> bool
  {
    self.stripping
  }
}

///
/// Function to split a string.
///
/// It produces former. To convert former into options and run algorithm of splitting call `form()`.
///
/// # Sample
/// ```
///   let iter = wstring_tools::string::split()
///   .src( "abc def" )
///   .delimeter( " " )
///   .perform();
/// ```

pub fn split< 'a >() -> SplitOptionsBuilder< 'a, &'a str >
{
  SplitOptionsBuilder::new( < &str >::default() )
}

}

/// Owned namespace of the module.
pub mod own
{
  use super::internal as i;

  pub use i::Split;
  pub use i::SplitType;
  pub use i::SplitIterator;
  pub use i::SplitOptions;
  pub use i::SplitOptionsAdapter;
  pub use i::split;
}

pub use own::*;

/// Exposed namespace of the module.
pub mod exposed
{
  use super::internal as i;

  pub use i::SplitOptionsAdapter;
  pub use i::split;
}

/// Namespace of the module to include with `use module::*`.
pub mod prelude
{
  use super::internal as i;

  pub use i::SplitOptionsAdapter;
}
<|endoftext|>


<commit_before>
use super::*;

#[repr(C)]
pub struct BStr( *mut u16 );

#[link(name = "oleaut32")]
extern "system" {
    pub fn SysAllocStringLen(
        psz: *const u16,
        len: u32
    ) -> BStr;
}

impl BStr {

    pub fn len_bytes( &self ) -> u32
    {
        unsafe {
            *(( self.0 as usize - 4 ) as *const u32 )
        }
    }

    pub fn string_to_bstr( s : &str ) -> BStr {

        let len = s.len() as u32;
        unsafe {
            SysAllocStringLen(
                s.encode_utf16().collect::<Vec<_>>().as_ptr(),
                len )
        }
    }

    pub fn bstr_to_string( &self ) -> String {

        let slice = unsafe { std::slice::from_raw_parts(
                self.0 as *const u16,
                ( self.len_bytes() as usize ) / 2 ) };
        String::from_utf16_lossy( slice )
    }
}

impl Default for BStr {
    fn default() -> Self { BStr( std::ptr::null_mut() ) }
}
<commit_msg>Give linux build a chance to go through<commit_after>
use super::*;

#[repr(C)]
pub struct BStr( *mut u16 );

#[cfg(windows)]
#[link(name = "oleaut32")]
extern "system" {
    pub fn SysAllocStringLen(
        psz: *const u16,
        len: u32
    ) -> BStr;
}

#[cfg(not(windows))]
pub fn SysAllocStringLen(
    psz: *const u16,
    len: u32
) -> BStr
{
    panic!( "Not implemented" );
}

impl BStr {

    pub fn len_bytes( &self ) -> u32
    {
        unsafe {
            *(( self.0 as usize - 4 ) as *const u32 )
        }
    }

    pub fn string_to_bstr( s : &str ) -> BStr {

        let len = s.len() as u32;
        unsafe {
            SysAllocStringLen(
                s.encode_utf16().collect::<Vec<_>>().as_ptr(),
                len )
        }
    }

    pub fn bstr_to_string( &self ) -> String {

        let slice = unsafe { std::slice::from_raw_parts(
                self.0 as *const u16,
                ( self.len_bytes() as usize ) / 2 ) };
        String::from_utf16_lossy( slice )
    }
}

impl Default for BStr {
    fn default() -> Self { BStr( std::ptr::null_mut() ) }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#![deny(warnings)]
#![deny(rust_2018_idioms)]
#![deny(clippy::all)]
#![allow(clippy::large_enum_variant)]

mod lexer;
mod node;
mod parser;
mod source;
mod syntax_error;
mod utils;

pub use lexer::TokenKind;
pub use node::*;
pub use parser::ParserFeatures;
pub use source::GraphQLSource;
pub use syntax_error::SyntaxError;
pub use utils::*;

use crate::parser::Parser;
use common::{DiagnosticsResult, SourceLocationKey, WithDiagnostics};

/// Parses a GraphQL document that might contain type system and executable
/// definitions.
pub fn parse_document(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<Document> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_document()
}

/// Parses a GraphQL document that might contain type system and executable
/// definitions with custom feature flags passed as `features`.
pub fn parse_document_with_features(
    source: &str,
    source_location: SourceLocationKey,
    features: ParserFeatures,
) -> DiagnosticsResult<Document> {
    let parser = Parser::new(source, source_location, features);
    parser.parse_document()
}

/// Parses a GraphQL document that's restricted to executable definitions.
pub fn parse_executable(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<ExecutableDocument> {
    parse_executable_with_error_recovery(source, source_location).into()
}

/// Parses a GraphQL document that's restricted to executable definitions,
/// with error recovery.
pub fn parse_executable_with_error_recovery(
    source: &str,
    source_location: SourceLocationKey,
) -> WithDiagnostics<ExecutableDocument> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_executable_document()
}

/// Parses a GraphQL document that's restricted to executable definitions,
/// with error recovery and customed ParserFeatures.
pub fn parse_executable_with_error_recovery_and_parser_features(
    source: &str,
    source_location: SourceLocationKey,
    features: ParserFeatures,
) -> WithDiagnostics<ExecutableDocument> {
    let parser = Parser::new(source, source_location, features);
    parser.parse_executable_document()
}

/// Parses a GraphQL document that's restricted to executable executable
/// definitions with custom feature flags passed as `features`.
pub fn parse_executable_with_features(
    source: &str,
    source_location: SourceLocationKey,
    features: ParserFeatures,
) -> DiagnosticsResult<ExecutableDocument> {
    parse_executable_with_error_recovery_and_parser_features(source, source_location, features)
        .into()
}

/// Parses a GraphQL document that's restricted to type system definitions
/// including schema definition, type definitions and type system extensions.
pub fn parse_schema_document(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<SchemaDocument> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_schema_document()
}

/// Parses a GraphQL type, such as `ID` or `[User!]!`.
pub fn parse_type(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<TypeAnnotation> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_type()
}

/// Parses a GraphQL document that's restricted to type system definitions
/// including schema definition, type definitions and type system extensions.
pub fn parse_directive(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<Directive> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_directive()
}
<commit_msg>Create merge schema<commit_after>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#![deny(warnings)]
#![deny(rust_2018_idioms)]
#![deny(clippy::all)]
#![allow(clippy::large_enum_variant)]

mod lexer;
mod node;
mod parser;
mod source;
mod syntax_error;
mod utils;

pub use lexer::TokenKind;
pub use node::*;
pub use parser::ParserFeatures;
pub use source::GraphQLSource;
pub use syntax_error::SyntaxError;
pub use utils::*;

use crate::parser::Parser;
use common::{DiagnosticsResult, SourceLocationKey, WithDiagnostics};

/// Parses a GraphQL document that might contain type system and executable
/// definitions.
pub fn parse_document(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<Document> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_document()
}

/// Parses a GraphQL document that might contain type system and executable
/// definitions with custom feature flags passed as `features`.
pub fn parse_document_with_features(
    source: &str,
    source_location: SourceLocationKey,
    features: ParserFeatures,
) -> DiagnosticsResult<Document> {
    let parser = Parser::new(source, source_location, features);
    parser.parse_document()
}

/// Parses a GraphQL document that's restricted to executable definitions.
pub fn parse_executable(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<ExecutableDocument> {
    parse_executable_with_error_recovery(source, source_location).into()
}

/// Parses a GraphQL document that's restricted to executable definitions,
/// with error recovery.
pub fn parse_executable_with_error_recovery(
    source: &str,
    source_location: SourceLocationKey,
) -> WithDiagnostics<ExecutableDocument> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_executable_document()
}

/// Parses a GraphQL document that's restricted to executable definitions,
/// with error recovery and customed ParserFeatures.
pub fn parse_executable_with_error_recovery_and_parser_features(
    source: &str,
    source_location: SourceLocationKey,
    features: ParserFeatures,
) -> WithDiagnostics<ExecutableDocument> {
    let parser = Parser::new(source, source_location, features);
    parser.parse_executable_document()
}

/// Parses a GraphQL document that's restricted to executable
/// definitions with custom feature flags passed as `features`.
pub fn parse_executable_with_features(
    source: &str,
    source_location: SourceLocationKey,
    features: ParserFeatures,
) -> DiagnosticsResult<ExecutableDocument> {
    parse_executable_with_error_recovery_and_parser_features(source, source_location, features)
        .into()
}

/// Parses a GraphQL document that's restricted to type system definitions
/// including schema definition, type definitions and type system extensions.
pub fn parse_schema_document(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<SchemaDocument> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_schema_document()
}

/// Parses a GraphQL type, such as `ID` or `[User!]!`.
pub fn parse_type(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<TypeAnnotation> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_type()
}

/// Parses a GraphQL document that's restricted to type system definitions
/// including schema definition, type definitions and type system extensions.
pub fn parse_directive(
    source: &str,
    source_location: SourceLocationKey,
) -> DiagnosticsResult<Directive> {
    let features = ParserFeatures::default();
    let parser = Parser::new(source, source_location, features);
    parser.parse_directive()
}
<|endoftext|>


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

//! Computed angles.

use std::{f32, f64, fmt};
use std::f64::consts::PI;
use style_traits::ToCss;
use values::CSSFloat;
use values::animated::{Animate, Procedure};
use values::distance::{ComputeSquaredDistance, SquaredDistance};

/// A computed angle.
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToAnimatedZero)]
pub enum Angle {
    /// An angle with degree unit.
    Degree(CSSFloat),
    /// An angle with gradian unit.
    Gradian(CSSFloat),
    /// An angle with radian unit.
    Radian(CSSFloat),
    /// An angle with turn unit.
    Turn(CSSFloat),
}

impl Angle {
    /// Creates a computed `Angle` value from a radian amount.
    pub fn from_radians(radians: CSSFloat) -> Self {
        Angle::Radian(radians)
    }

    /// Returns the amount of radians this angle represents.
    #[inline]
    pub fn radians(&self) -> CSSFloat {
        self.radians64().min(f32::MAX as f64).max(f32::MIN as f64) as f32
    }

    /// Returns the amount of radians this angle represents as a `f64`.
    ///
    /// Gecko stores angles as singles, but does this computation using doubles.
    /// See nsCSSValue::GetAngleValueInRadians.
    /// This is significant enough to mess up rounding to the nearest
    /// quarter-turn for 225 degrees, for example.
    #[inline]
    pub fn radians64(&self) -> f64 {
        const RAD_PER_DEG: f64 = PI / 180.0;
        const RAD_PER_GRAD: f64 = PI / 200.0;
        const RAD_PER_TURN: f64 = PI * 2.0;

        let radians = match *self {
            Angle::Degree(val) => val as f64 * RAD_PER_DEG,
            Angle::Gradian(val) => val as f64 * RAD_PER_GRAD,
            Angle::Turn(val) => val as f64 * RAD_PER_TURN,
            Angle::Radian(val) => val as f64,
        };
        radians.min(f64::MAX).max(f64::MIN)
    }

    /// Returns an angle that represents a rotation of zero radians.
    pub fn zero() -> Self {
        Angle::Radian(0.0)
    }
}

/// https://drafts.csswg.org/css-transitions/#animtype-number
impl Animate for Angle {
    #[inline]
    fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
        match (self, other) {
            (&Angle::Degree(ref this), &Angle::Degree(ref other)) => {
                Ok(Angle::Degree(this.animate(other, procedure)?))
            },
            (&Angle::Gradian(ref this), &Angle::Gradian(ref other)) => {
                Ok(Angle::Gradian(this.animate(other, procedure)?))
            },
            (&Angle::Turn(ref this), &Angle::Turn(ref other)) => {
                Ok(Angle::Turn(this.animate(other, procedure)?))
            },
            _ => {
                Ok(Angle::from_radians(self.radians().animate(&other.radians(), procedure)?))
            },
        }
    }
}

impl ComputeSquaredDistance for Angle {
    #[inline]
    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
        // Use the formula for calculating the distance between angles defined in SVG:
        // https://www.w3.org/TR/SVG/animate.html#complexDistances
        self.radians64().compute_squared_distance(&other.radians64())
    }
}

impl ToCss for Angle {
    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
    where
        W: fmt::Write,
    {
        let mut write = |value: CSSFloat, unit: &str| {
            value.to_css(dest)?;
            dest.write_str(unit)
        };

        match *self {
            Angle::Degree(val) => write(val, "deg"),
            Angle::Gradian(val) => write(val, "grad"),
            Angle::Radian(val) => write(val, "rad"),
            Angle::Turn(val) => write(val, "turn"),
        }
    }
}
<commit_msg>Derive Animate for computed::Angle<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Computed angles.

use std::{f32, f64, fmt};
use std::f64::consts::PI;
use style_traits::ToCss;
use values::CSSFloat;
use values::animated::{Animate, Procedure};
use values::distance::{ComputeSquaredDistance, SquaredDistance};

/// A computed angle.
#[animate(fallback = "Self::animate_fallback")]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
#[derive(Animate, Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
#[derive(PartialOrd, ToAnimatedZero)]
pub enum Angle {
    /// An angle with degree unit.
    Degree(CSSFloat),
    /// An angle with gradian unit.
    Gradian(CSSFloat),
    /// An angle with radian unit.
    Radian(CSSFloat),
    /// An angle with turn unit.
    Turn(CSSFloat),
}

impl Angle {
    /// Creates a computed `Angle` value from a radian amount.
    pub fn from_radians(radians: CSSFloat) -> Self {
        Angle::Radian(radians)
    }

    /// Returns the amount of radians this angle represents.
    #[inline]
    pub fn radians(&self) -> CSSFloat {
        self.radians64().min(f32::MAX as f64).max(f32::MIN as f64) as f32
    }

    /// Returns the amount of radians this angle represents as a `f64`.
    ///
    /// Gecko stores angles as singles, but does this computation using doubles.
    /// See nsCSSValue::GetAngleValueInRadians.
    /// This is significant enough to mess up rounding to the nearest
    /// quarter-turn for 225 degrees, for example.
    #[inline]
    pub fn radians64(&self) -> f64 {
        const RAD_PER_DEG: f64 = PI / 180.0;
        const RAD_PER_GRAD: f64 = PI / 200.0;
        const RAD_PER_TURN: f64 = PI * 2.0;

        let radians = match *self {
            Angle::Degree(val) => val as f64 * RAD_PER_DEG,
            Angle::Gradian(val) => val as f64 * RAD_PER_GRAD,
            Angle::Turn(val) => val as f64 * RAD_PER_TURN,
            Angle::Radian(val) => val as f64,
        };
        radians.min(f64::MAX).max(f64::MIN)
    }

    /// Returns an angle that represents a rotation of zero radians.
    pub fn zero() -> Self {
        Angle::Radian(0.0)
    }

    /// https://drafts.csswg.org/css-transitions/#animtype-number
    #[inline]
    fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
        Ok(Angle::from_radians(self.radians().animate(&other.radians(), procedure)?))
    }
}

impl ComputeSquaredDistance for Angle {
    #[inline]
    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
        // Use the formula for calculating the distance between angles defined in SVG:
        // https://www.w3.org/TR/SVG/animate.html#complexDistances
        self.radians64().compute_squared_distance(&other.radians64())
    }
}

impl ToCss for Angle {
    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
    where
        W: fmt::Write,
    {
        let mut write = |value: CSSFloat, unit: &str| {
            value.to_css(dest)?;
            dest.write_str(unit)
        };

        match *self {
            Angle::Degree(val) => write(val, "deg"),
            Angle::Gradian(val) => write(val, "grad"),
            Angle::Radian(val) => write(val, "rad"),
            Angle::Turn(val) => write(val, "turn"),
        }
    }
}
<|endoftext|>