#![cfg_attr(feature = "nightly", feature(track_path))]
use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
mod args;
mod cold;
mod formats;
mod metadata;
mod parse;
use self::{
metadata::DepthChannels,
parse::{Magic, Reader},
};
use crate::formats::Nesting;
fn include_file(depth_channels: DepthChannels, nesting: Nesting, path: String) -> TokenStream {
let span = Span::call_site();
if span.file().is_empty() && span.local_file().is_none() {
eprintln!("warning: rust-analyzer does not implement `Span::local_file`");
eprintln!(
"warning: see this issue: https://github.com/rust-lang/rust-analyzer/issues/1595"
);
let mut result = TokenStream::new();
result.extend(Some(TokenTree::Ident(Ident::new("unsafe", span))));
{
let mut block = TokenStream::new();
block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Alone))));
block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Joint))));
block.extend(Some(TokenTree::Ident(Ident::new("core", span))));
block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Alone))));
block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Joint))));
block.extend(Some(TokenTree::Ident(Ident::new("mem", span))));
block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Alone))));
block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Joint))));
block.extend(Some(TokenTree::Ident(Ident::new("zeroed", span))));
block.extend(Some(TokenTree::Group(Group::new(
Delimiter::Parenthesis,
TokenStream::new(),
))));
result.extend(Some(TokenTree::Group(Group::new(Delimiter::Brace, block))));
}
result
} else {
#[cfg(feature = "nightly")]
{
proc_macro::tracked_path::path(&path);
}
let mut reader = Reader::open(&path);
match reader.read_magic() {
Magic::P1 => formats::load_plain_pbm(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
Magic::P2 => formats::load_plain_pgm(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
Magic::P3 => formats::load_plain_ppm(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
Magic::P4 => formats::load_pbm(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
Magic::P5 => formats::load_pgm(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
Magic::P6 => formats::load_ppm(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
Magic::P7 => formats::load_pam(&mut reader)
.convert(depth_channels)
.into_tokens(nesting),
}
}
}
#[proc_macro]
pub fn include_pnm(input: TokenStream) -> TokenStream {
let caller = "include_pnm";
let mut input = input.into_iter();
let depth_channels = args::get_depth_channels(caller, &mut input);
let file = args::get_file(caller, &mut input, Some(args::LeadingComma));
include_file(depth_channels, Nesting::Arrays, file)
}
#[proc_macro]
pub fn include_pbm(input: TokenStream) -> TokenStream {
let file = args::get_file("include_pbm", &mut input.into_iter(), None);
include_file(DepthChannels::BlackAndWhite, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_pbma(input: TokenStream) -> TokenStream {
let file = args::get_file("include_pbma", &mut input.into_iter(), None);
include_file(DepthChannels::BlackAndWhiteAlpha, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_pgm(input: TokenStream) -> TokenStream {
let file = args::get_file("include_pgm", &mut input.into_iter(), None);
include_file(DepthChannels::Grayscale, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_pgma(input: TokenStream) -> TokenStream {
let file = args::get_file("include_pgma", &mut input.into_iter(), None);
include_file(DepthChannels::GrayscaleAlpha, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_pgm16(input: TokenStream) -> TokenStream {
let file = args::get_file("include_pgm16", &mut input.into_iter(), None);
include_file(DepthChannels::Grayscale16, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_pgma16(input: TokenStream) -> TokenStream {
let file = args::get_file("include_pgma", &mut input.into_iter(), None);
include_file(DepthChannels::GrayscaleAlpha16, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_ppm(input: TokenStream) -> TokenStream {
let file = args::get_file("include_ppm", &mut input.into_iter(), None);
include_file(DepthChannels::Rgb, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_ppma(input: TokenStream) -> TokenStream {
let file = args::get_file("include_ppm", &mut input.into_iter(), None);
include_file(DepthChannels::RgbAlpha, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_ppm16(input: TokenStream) -> TokenStream {
let file = args::get_file("include_ppm16", &mut input.into_iter(), None);
include_file(DepthChannels::Rgb16, Nesting::Inline, file)
}
#[proc_macro]
pub fn include_ppma16(input: TokenStream) -> TokenStream {
let file = args::get_file("include_ppm16", &mut input.into_iter(), None);
include_file(DepthChannels::RgbAlpha16, Nesting::Inline, file)
}