<commit_before>use std::io::{Read, Seek};
use std::mem;

use Result;
use postscript::compact::FontSet;
use tape::Tape;
use truetype::compound::{CharMapping, FontHeader, HorizontalHeader, HorizontalMetrics};
use truetype::compound::{OffsetTable, MaximumProfile, NamingTable, PostScriptInfo, WindowsMetrics};
use truetype::primitive::Tag;
use truetype;

/// A font file.
#[derive(Default)]
pub struct File {
    pub offset_table: OffsetTable,
    pub char_mapping: Option<CharMapping>,
    pub font_header: Option<FontHeader>,
    pub horizontal_header: Option<HorizontalHeader>,
    pub horizontal_metrics: Option<HorizontalMetrics>,
    pub maximum_profile: Option<MaximumProfile>,
    pub naming_table: Option<NamingTable>,
    pub postscript_info: Option<PostScriptInfo>,
    pub windows_metrics: Option<WindowsMetrics>,
    pub postscript_fontset: Option<FontSet>,
}

macro_rules! checksum_and_jump(
    ($record:ident, $tape:ident, $process:expr) => ({
        if !try!($record.checksum($tape, $process)) {
            raise!("found a corrupted font table");
        }
        try!($tape.jump($record.offset as u64));
    });
    ($record:ident, $tape:ident) => (
        checksum_and_jump!($record, $tape, |_, word| word);
    );
);

impl File {
    #[inline]
    pub fn read<T: Read + Seek>(tape: &mut T) -> Result<File> {
        macro_rules! sort(
            ($records:expr) => ({
                let mut records = $records.iter().collect::<Vec<_>>();
                records.sort_by(|one, two| priority(Tag(one.tag)).cmp(&priority(Tag(two.tag))));
                records
            });<commit_msg>Add open to File<commit_after>use std::io::{Read, Seek};
use std::path::Path;
use std::{fs, mem};

use Result;
use postscript::compact::FontSet;
use tape::Tape;
use truetype::compound::{CharMapping, FontHeader, HorizontalHeader, HorizontalMetrics};
use truetype::compound::{OffsetTable, MaximumProfile, NamingTable, PostScriptInfo, WindowsMetrics};
use truetype::primitive::Tag;
use truetype;

/// A font file.
#[derive(Default)]
pub struct File {
    pub offset_table: OffsetTable,
    pub char_mapping: Option<CharMapping>,
    pub font_header: Option<FontHeader>,
    pub horizontal_header: Option<HorizontalHeader>,
    pub horizontal_metrics: Option<HorizontalMetrics>,
    pub maximum_profile: Option<MaximumProfile>,
    pub naming_table: Option<NamingTable>,
    pub postscript_info: Option<PostScriptInfo>,
    pub windows_metrics: Option<WindowsMetrics>,
    pub postscript_fontset: Option<FontSet>,
}

macro_rules! checksum_and_jump(
    ($record:ident, $tape:ident, $process:expr) => ({
        if !try!($record.checksum($tape, $process)) {
            raise!("found a corrupted font table");
        }
        try!($tape.jump($record.offset as u64));
    });
    ($record:ident, $tape:ident) => (
        checksum_and_jump!($record, $tape, |_, word| word);
    );
);

impl File {
    #[inline]
    pub fn open<T: AsRef<Path>>(path: T) -> Result<File> {
        let mut file = try!(fs::File::open(path));
        File::read(&mut file)
    }

    pub fn read<T: Read + Seek>(tape: &mut T) -> Result<File> {
        macro_rules! sort(
            ($records:expr) => ({
                let mut records = $records.iter().collect::<Vec<_>>();
                records.sort_by(|one, two| priority(Tag(one.tag)).cmp(&priority(Tag(two.tag))));
                records
            });
{'fraction_non_alphanumeric': 0.15139911634756995, 'fraction_numerical': 0.00117820324005891, 'mean_word_length': 3.7496503496503495, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '593652', 'n_tokens_mistral': 1083, 'n_tokens_neox': 1056, 'n_words': 232}