1#![cfg_attr(feature = "nightly", feature(track_path))]
33use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
34
35mod args;
36mod cold;
37mod formats;
38mod metadata;
39mod parse;
40use self::{
41 metadata::DepthChannels,
42 parse::{Magic, Reader},
43};
44use crate::formats::Nesting;
45
46fn include_file(depth_channels: DepthChannels, nesting: Nesting, path: String) -> TokenStream {
48 let span = Span::call_site();
49
50 if span.file().is_empty() && span.local_file().is_none() {
53 eprintln!("warning: rust-analyzer does not implement `Span::local_file`");
54 eprintln!(
55 "warning: see this issue: https://github.com/rust-lang/rust-analyzer/issues/1595"
56 );
57
58 let mut result = TokenStream::new();
60 result.extend(Some(TokenTree::Ident(Ident::new("unsafe", span))));
61 {
62 let mut block = TokenStream::new();
63 block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Alone))));
64 block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Joint))));
65 block.extend(Some(TokenTree::Ident(Ident::new("core", span))));
66 block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Alone))));
67 block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Joint))));
68 block.extend(Some(TokenTree::Ident(Ident::new("mem", span))));
69 block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Alone))));
70 block.extend(Some(TokenTree::Punct(Punct::new(':', Spacing::Joint))));
71 block.extend(Some(TokenTree::Ident(Ident::new("zeroed", span))));
72 block.extend(Some(TokenTree::Group(Group::new(
73 Delimiter::Parenthesis,
74 TokenStream::new(),
75 ))));
76 result.extend(Some(TokenTree::Group(Group::new(Delimiter::Brace, block))));
77 }
78 result
79 } else {
80 #[cfg(feature = "nightly")]
81 {
82 proc_macro::tracked_path::path(&path);
83 }
84 let mut reader = Reader::open(&path);
85 match reader.read_magic() {
86 Magic::P1 => formats::load_plain_pbm(&mut reader)
87 .convert(depth_channels)
88 .into_tokens(nesting),
89 Magic::P2 => formats::load_plain_pgm(&mut reader)
90 .convert(depth_channels)
91 .into_tokens(nesting),
92 Magic::P3 => formats::load_plain_ppm(&mut reader)
93 .convert(depth_channels)
94 .into_tokens(nesting),
95 Magic::P4 => formats::load_pbm(&mut reader)
96 .convert(depth_channels)
97 .into_tokens(nesting),
98 Magic::P5 => formats::load_pgm(&mut reader)
99 .convert(depth_channels)
100 .into_tokens(nesting),
101 Magic::P6 => formats::load_ppm(&mut reader)
102 .convert(depth_channels)
103 .into_tokens(nesting),
104 Magic::P7 => formats::load_pam(&mut reader)
105 .convert(depth_channels)
106 .into_tokens(nesting),
107 }
108 }
109}
110
111#[proc_macro]
128pub fn include_pnm(input: TokenStream) -> TokenStream {
129 let caller = "include_pnm";
130 let mut input = input.into_iter();
131 let depth_channels = args::get_depth_channels(caller, &mut input);
132 let file = args::get_file(caller, &mut input, Some(args::LeadingComma));
133 include_file(depth_channels, Nesting::Arrays, file)
134}
135
136#[proc_macro]
140pub fn include_pbm(input: TokenStream) -> TokenStream {
141 let file = args::get_file("include_pbm", &mut input.into_iter(), None);
142 include_file(DepthChannels::BlackAndWhite, Nesting::Inline, file)
143}
144
145#[proc_macro]
149pub fn include_pbma(input: TokenStream) -> TokenStream {
150 let file = args::get_file("include_pbma", &mut input.into_iter(), None);
151 include_file(DepthChannels::BlackAndWhiteAlpha, Nesting::Inline, file)
152}
153
154#[proc_macro]
158pub fn include_pgm(input: TokenStream) -> TokenStream {
159 let file = args::get_file("include_pgm", &mut input.into_iter(), None);
160 include_file(DepthChannels::Grayscale, Nesting::Inline, file)
161}
162
163#[proc_macro]
167pub fn include_pgma(input: TokenStream) -> TokenStream {
168 let file = args::get_file("include_pgma", &mut input.into_iter(), None);
169 include_file(DepthChannels::GrayscaleAlpha, Nesting::Inline, file)
170}
171
172#[proc_macro]
176pub fn include_pgm16(input: TokenStream) -> TokenStream {
177 let file = args::get_file("include_pgm16", &mut input.into_iter(), None);
178 include_file(DepthChannels::Grayscale16, Nesting::Inline, file)
179}
180
181#[proc_macro]
185pub fn include_pgma16(input: TokenStream) -> TokenStream {
186 let file = args::get_file("include_pgma", &mut input.into_iter(), None);
187 include_file(DepthChannels::GrayscaleAlpha16, Nesting::Inline, file)
188}
189
190#[proc_macro]
194pub fn include_ppm(input: TokenStream) -> TokenStream {
195 let file = args::get_file("include_ppm", &mut input.into_iter(), None);
196 include_file(DepthChannels::Rgb, Nesting::Inline, file)
197}
198
199#[proc_macro]
203pub fn include_ppma(input: TokenStream) -> TokenStream {
204 let file = args::get_file("include_ppm", &mut input.into_iter(), None);
205 include_file(DepthChannels::RgbAlpha, Nesting::Inline, file)
206}
207
208#[proc_macro]
212pub fn include_ppm16(input: TokenStream) -> TokenStream {
213 let file = args::get_file("include_ppm16", &mut input.into_iter(), None);
214 include_file(DepthChannels::Rgb16, Nesting::Inline, file)
215}
216
217#[proc_macro]
221pub fn include_ppma16(input: TokenStream) -> TokenStream {
222 let file = args::get_file("include_ppm16", &mut input.into_iter(), None);
223 include_file(DepthChannels::RgbAlpha16, Nesting::Inline, file)
224}