1use std::env;
166
167use indoc::formatdoc;
168use proc_macro2::{Ident, Span, TokenStream};
169use proc_macro_error::{abort, proc_macro_error};
170use quote::{format_ident, quote};
171use syn::{parse_macro_input, spanned::Spanned, Data, DeriveInput};
172
173mod attribute;
174mod byteset;
175mod charset;
176mod grammar;
177mod options;
178mod token;
179mod utils;
180
181use attribute::Attribute;
182use byteset::ByteSet;
183use charset::CharSet;
184use grammar::{extract_grammar, Grammar, GrammarError};
185use options::*;
186use token::{Token, TokenSet};
187use utils::{automaton::DetAutomaton, SnakeCase};
188
189#[proc_macro_derive(RegularGrammar, attributes(grammar))]
190#[proc_macro_error]
191pub fn derive_regular_grammar(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
192 let input = parse_macro_input!(input_tokens as DeriveInput);
193 match generate_regular_grammar(input) {
194 Ok(tokens) => tokens.into(),
195 Err((e, span)) => abort!(span, e),
196 }
197}
198
199#[derive(Debug, thiserror::Error)]
200pub(crate) enum Error {
201 #[error(transparent)]
202 Var(env::VarError),
203
204 #[error("unexpected type parameter")]
205 UnexpectedTypeParameter,
206
207 #[error("unexpected union type")]
208 UnexpectedUnion,
209
210 #[error("unexpected enum type")]
211 UnexpectedEnum,
212
213 #[error("unexpected unit structure")]
214 UnexpectedUnitStruct,
215
216 #[error("unexpected nammed fields")]
217 UnexpectedNamedFields,
218
219 #[error("missing unnamed field")]
220 MissingField,
221
222 #[error("unexpected unnamed field")]
223 UnexpectedUnnamedField,
224
225 #[error("unsafe visibility")]
226 UnsafeVisibility,
227
228 #[error("invalid inner type")]
229 InvalidInnerType,
230
231 #[error("`grammar` attribute error: {0}")]
232 Attribute(#[from] attribute::Error),
233
234 #[error(transparent)]
235 Grammar(GrammarError),
236
237 #[error("target directory not found: {0}")]
238 TargetDirNotFound(std::env::VarError),
239
240 #[error("missing sized type identifier")]
241 MissingSizedTypeIdent,
242
243 #[error("grammar is not ASCII")]
244 NotAscii,
245}
246
247enum TokenType {
248 Bytes,
249 String,
250}
251
252fn is_str_path(path: &syn::Path) -> bool {
253 path.is_ident("str")
254}
255
256fn is_u8_path(path: &syn::Path) -> bool {
257 path.is_ident("u8")
258}
259
260impl TokenType {
261 fn from_type(ty: syn::Type) -> Result<Self, (Error, Span)> {
262 match ty {
263 syn::Type::Slice(ty) => Self::from_array_element_type(*ty.elem),
264 syn::Type::Path(ty) if is_str_path(&ty.path) => Ok(Self::String),
265 ty => Err((Error::InvalidInnerType, ty.span())),
266 }
267 }
268
269 fn from_array_element_type(ty: syn::Type) -> Result<Self, (Error, Span)> {
270 match ty {
271 syn::Type::Path(ty) if is_u8_path(&ty.path) => Ok(Self::Bytes),
272 ty => Err((Error::InvalidInnerType, ty.span())),
273 }
274 }
275}
276
277struct GrammarData {
278 vis: syn::Visibility,
279 ident: Ident,
280 token: TokenType,
281 options: Options,
282}
283
284fn extract_grammar_data(
285 input: DeriveInput,
286) -> Result<(GrammarData, Vec<syn::Attribute>), (Error, Span)> {
287 match input.data {
288 Data::Struct(s) => match s.fields {
289 syn::Fields::Unit => Err((Error::UnexpectedUnitStruct, s.fields.span())),
290 syn::Fields::Named(_) => Err((Error::UnexpectedNamedFields, s.fields.span())),
291 syn::Fields::Unnamed(fields) => {
292 let fields_span = fields.span();
293 let mut iter = fields.unnamed.into_iter();
294
295 match iter.next() {
296 Some(field) => match iter.next() {
297 Some(f) => Err((Error::UnexpectedUnnamedField, f.span())),
298 None => match field.vis {
299 syn::Visibility::Inherited => {
300 let mut grammar_attr = Attribute::default();
301 let mut attrs_rest = Vec::with_capacity(input.attrs.len());
302 for attr in input.attrs {
303 if attr.meta.path().is_ident("grammar") {
304 grammar_attr
305 .append(Attribute::parse(attr).map_err(
306 |(e, span)| (Error::Attribute(e), span),
307 )?);
308 } else if attr.meta.path().is_ident("cfg_attr") {
309 grammar_attr.disable = true
314 } else {
315 attrs_rest.push(attr);
316 }
317 }
318
319 let options = Options::from_attribute(&input.ident, grammar_attr)?;
320
321 Ok((
322 GrammarData {
323 vis: input.vis,
324 ident: input.ident,
325 token: TokenType::from_type(field.ty)?,
326 options,
327 },
328 attrs_rest,
329 ))
330 }
331 vis => Err((Error::UnsafeVisibility, vis.span())),
332 },
333 },
334 None => Err((Error::MissingField, fields_span)),
335 }
336 }
337 },
338 Data::Union(u) => Err((Error::UnexpectedUnion, u.union_token.span())),
339 Data::Enum(e) => Err((Error::UnexpectedEnum, e.enum_token.span())),
340 }
341}
342
343fn generate_regular_grammar(input: DeriveInput) -> Result<TokenStream, (Error, Span)> {
344 match input.generics.params.iter().next() {
345 Some(param) => Err((Error::UnexpectedTypeParameter, param.span())),
346 None => {
347 let (data, attrs) = extract_grammar_data(input)?;
348 match data.token {
349 TokenType::Bytes => generate_typed::<u8>(data, attrs),
350 TokenType::String => generate_typed::<char>(data, attrs),
351 }
352 }
353 }
354}
355
356fn generate_typed<T: Token>(
357 data: GrammarData,
358 attrs: Vec<syn::Attribute>,
359) -> Result<TokenStream, (Error, Span)> {
360 let automaton = if data.options.disable {
361 let mut aut = DetAutomaton::new(0);
362 aut.declare_state(0);
363 aut.add_final_state(0);
364 aut
365 } else {
366 let (grammar, hash) = extract_grammar::<T>(
367 &data.options.cache_path,
368 data.options.file.as_deref(),
369 data.options.entry_point.as_deref(),
370 attrs,
371 )
372 .map_err(|(e, span)| (Error::Grammar(e), span))?;
373 let cached = grammar.is_cached();
374 let automaton = grammar.build_automaton();
375
376 if !cached {
377 if let Err(e) = Grammar::<T>::save_to_file(&data.options.cache_path, hash, &automaton) {
378 eprintln!("unable to cache regular automaton: {e}")
379 }
380 }
381
382 automaton
383 };
384
385 let contains_empty = automaton.contains_empty();
386
387 let vis = data.vis;
388 let ident = data.ident;
389 let ascii = data.options.ascii && T::is_ascii(&automaton);
390 let name = data
391 .options
392 .name
393 .or(data.options.entry_point)
394 .unwrap_or_else(|| ident.to_string());
395
396 if data.options.ascii && !ascii {
397 return Err((Error::NotAscii, Span::call_site()));
398 }
399
400 let as_ref = format_ident!("as_{}", SnakeCase(&ident.to_string()));
401
402 let token_type = T::rust_type();
403 let string_type = T::rust_string_type();
404 let iterator_method = T::rust_iterator_method();
405
406 let as_inner = T::rust_as_inner_method();
407
408 let error = format_ident!("Invalid{}", ident);
409 let error_msg = format!("Invalid {name} `{{0}}`");
410
411 let new_doc = format!("Creates a new {name} by parsing the `input` value");
412 let new_unchecked_doc = formatdoc!(
413 r#"
414 Creates a new {name} from the `input` value without validation.
415
416 # Safety
417
418 The input data *must* be a valid {name}."#
419 );
420
421 let validate_doc = format!("Checks that the input iterator produces a valid {name}");
422 let validate_body = if data.options.disable {
423 quote! {
424 panic!("automaton not generated")
425 }
426 } else {
427 generate_validation_function::<T>(&automaton)
428 };
429
430 let mut tokens = quote! {
431 #[derive(Debug)]
432 #vis struct #error<T>(pub T);
433
434 impl<T: ::core::fmt::Display> ::core::fmt::Display for #error<T> {
435 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
436 write!(f, #error_msg, self.0)
437 }
438 }
439
440 impl<T: ::core::fmt::Debug + ::core::fmt::Display> ::std::error::Error for #error<T> {}
441
442 impl #ident {
443 #[doc = #new_doc]
444 pub fn new<T: ?Sized + AsRef<#string_type>>(input: &T) -> Result<&Self, #error<&T>> {
445 let input_ref = input.as_ref();
446 if Self::validate(input_ref.#iterator_method) {
447 Ok(unsafe {
448 Self::new_unchecked(input_ref)
449 })
450 } else {
451 Err(#error(input))
452 }
453 }
454
455 #[doc = #new_unchecked_doc]
456 pub const unsafe fn new_unchecked(input: &#string_type) -> &Self {
457 ::core::mem::transmute(input)
458 }
459
460 #[doc = #validate_doc]
461 #[allow(unreachable_code)]
462 pub fn validate(mut input: impl Iterator<Item = #token_type>) -> bool {
463 #validate_body
464 }
465 }
466
467 impl AsRef<#ident> for #ident {
468 fn as_ref(&self) -> &#ident {
469 self
470 }
471 }
472
473 impl<'a> TryFrom<&'a #string_type> for &'a #ident {
474 type Error = #error<&'a #string_type>;
475
476 fn try_from(input: &'a #string_type) -> Result<&'a #ident, #error<&'a #string_type>> {
477 #ident::new(input)
478 }
479 }
480
481 impl<'a> From<&'a #ident> for &'a #string_type {
482 fn from(value: &'a #ident) -> &'a #string_type {
483 &value.0
484 }
485 }
486 };
487
488 if contains_empty {
489 let empty_string = T::rust_empty_string();
490 tokens.extend(quote! {
491 impl #ident {
492 pub const EMPTY: &'static Self = unsafe {
493 Self::new_unchecked(#empty_string)
494 };
495 }
496 })
497 }
498
499 if !data.options.no_borrow {
500 let as_bytes = T::rust_inner_as_bytes_method().map(|as_bytes| {
501 quote! {
502 pub fn as_bytes(&self) -> &[u8] {
503 self.0.#as_bytes()
504 }
505 }
506 });
507
508 let borrow_bytes = T::rust_inner_as_bytes_method().map(|as_bytes| {
509 quote! {
510 impl ::core::convert::AsRef<[u8]> for #ident {
511 fn as_ref(&self) -> &[u8] {
512 self.0.#as_bytes()
513 }
514 }
515 }
516 });
517
518 tokens.extend(quote! {
519 impl #ident {
520 pub fn #as_inner(&self) -> &#string_type {
521 &self.0
522 }
523
524 #as_bytes
525 }
526
527 impl ::core::borrow::Borrow<#string_type> for #ident {
528 fn borrow(&self) -> &#string_type {
529 &self.0
530 }
531 }
532
533 impl ::core::convert::AsRef<#string_type> for #ident {
534 fn as_ref(&self) -> &#string_type {
535 &self.0
536 }
537 }
538
539 #borrow_bytes
540 });
541
542 if ascii {
543 if let Some(as_ascii) = T::rust_inner_as_ascii_method_body() {
544 tokens.extend(quote! {
545 impl #ident {
546 pub fn as_str(&self) -> &str {
547 #as_ascii
548 }
549 }
550
551 impl ::core::convert::AsRef<str> for #ident {
552 fn as_ref(&self) -> &str {
553 #as_ascii
554 }
555 }
556
557 impl<'a> TryFrom<&'a str> for &'a #ident {
558 type Error = #error<&'a str>;
559
560 fn try_from(input: &'a str) -> Result<&'a #ident, #error<&'a str>> {
561 #ident::new(input.as_bytes()).map_err(|_| #error(input))
562 }
563 }
564
565 impl<'a> From<&'a #ident> for &'a str {
566 fn from(value: &'a #ident) -> &'a str {
567 value.as_str()
568 }
569 }
570 })
571 }
572 }
573 }
574
575 if !data.options.no_deref {
576 match T::rust_inner_as_ascii_method_body() {
577 Some(as_ascii) if ascii => tokens.extend(quote! {
578 impl ::core::ops::Deref for #ident {
579 type Target = str;
580
581 fn deref(&self) -> &str {
582 #as_ascii
583 }
584 }
585 }),
586 _ => tokens.extend(quote! {
587 impl ::core::ops::Deref for #ident {
588 type Target = #string_type;
589
590 fn deref(&self) -> &#string_type {
591 &self.0
592 }
593 }
594 }),
595 }
596 }
597
598 if T::UNICODE || ascii {
599 tokens.extend(quote! {
600 impl ::core::fmt::Display for #ident {
601 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
602 ::core::fmt::Display::fmt(self.as_str(), f)
603 }
604 }
605
606 impl ::core::fmt::Debug for #ident {
607 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
608 ::core::fmt::Debug::fmt(self.as_str(), f)
609 }
610 }
611 });
612 }
613
614 if data.options.serde {
615 let serialize = if T::UNICODE || ascii {
616 quote! {
617 serializer.serialize_str(self.as_str())
618 }
619 } else {
620 quote! {
621 serializer.serialize_bytes(self.as_bytes())
622 }
623 };
624
625 let visit_bytes = if T::UNICODE {
626 quote! {
627 match std::str::from_utf8(v) {
628 Ok(s) => #ident::new(s).map_err(|_| ()),
629 Err(e) => Err(())
630 }
631 }
632 } else {
633 quote! {
634 #ident::new(v)
635 }
636 };
637
638 let expected = format!("some {ident}");
639
640 tokens.extend(quote! {
641 impl ::serde::Serialize for #ident {
642 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
643 where
644 S: ::serde::Serializer
645 {
646 #serialize
647 }
648 }
649
650 impl<'a, 'de: 'a> ::serde::Deserialize<'de> for &'a #ident {
651 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
652 where
653 D: ::serde::Deserializer<'de>
654 {
655 struct Visitor;
656
657 impl<'de> ::serde::de::Visitor<'de> for Visitor {
658 type Value = &'de #ident;
659
660 fn expecting(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
661 write!(f, #expected)
662 }
663
664 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
665 where
666 E: ::serde::de::Error
667 {
668 #ident::new(v).map_err(|_| E::invalid_value(::serde::de::Unexpected::Str(v), &self))
669 }
670
671 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
672 where
673 E: ::serde::de::Error
674 {
675 #visit_bytes.map_err(|_| E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
676 }
677 }
678
679 deserializer.deserialize_str(Visitor)
680 }
681 }
682 })
683 }
684
685 if let Some(buffer) = data.options.sized {
686 let buffer_ident = buffer.ident;
687 let owned_string_type = T::rust_owned_string_type();
688
689 let owned_doc = format!("Owned {name}.");
690 let owned_new_doc = format!("Creates a new owned {name} by parsing the `input` value");
691 let owned_new_unchecked_doc = formatdoc!(
692 r#"
693 Creates a new owned {name} from the `input` value without validation.
694
695 # Safety
696
697 The input data *must* be a valid {name}."#
698 );
699
700 tokens.extend(quote! {
701 #[doc = #owned_doc]
702 #[derive(Clone)]
703 #vis struct #buffer_ident(#owned_string_type);
704
705 impl #buffer_ident {
706 #[doc = #owned_new_doc]
707 pub fn new(input: #owned_string_type) -> Result<Self, #error<#owned_string_type>> {
708 if #ident::validate(input.#iterator_method) {
709 Ok(Self(input))
710 } else {
711 Err(#error(input))
712 }
713 }
714
715 #[doc = #owned_new_unchecked_doc]
716 pub const unsafe fn new_unchecked(input: #owned_string_type) -> Self {
717 Self(input)
718 }
719
720 pub fn #as_ref(&self) -> &#ident {
721 unsafe {
722 #ident::new_unchecked(&self.0)
723 }
724 }
725 }
726
727 impl ::core::ops::Deref for #buffer_ident {
728 type Target = #ident;
729
730 fn deref(&self) -> &Self::Target {
731 self.#as_ref()
732 }
733 }
734
735 impl ::core::borrow::Borrow<#ident> for #buffer_ident {
736 fn borrow(&self) -> &#ident {
737 self.#as_ref()
738 }
739 }
740
741 impl ::core::convert::AsRef<#ident> for #buffer_ident {
742 fn as_ref(&self) -> &#ident {
743 self.#as_ref()
744 }
745 }
746
747 impl ::std::borrow::ToOwned for #ident {
748 type Owned = #buffer_ident;
749
750 fn to_owned(&self) -> #buffer_ident {
751 unsafe {
752 #buffer_ident::new_unchecked(
753 self.0.to_owned()
754 )
755 }
756 }
757 }
758
759 impl TryFrom<#owned_string_type> for #buffer_ident {
760 type Error = #error<#owned_string_type>;
761
762 fn try_from(input: #owned_string_type) -> Result<#buffer_ident, #error<#owned_string_type>> {
763 #buffer_ident::new(input)
764 }
765 }
766
767 impl From<#buffer_ident> for #owned_string_type {
768 fn from(value: #buffer_ident) -> #owned_string_type {
769 value.0
770 }
771 }
772 });
773
774 if !T::UNICODE && ascii {
775 tokens.extend(quote! {
776 impl #buffer_ident {
777 pub fn into_string(self) -> ::std::string::String {
778 unsafe {
779 ::std::string::String::from_utf8_unchecked(self.0)
780 }
781 }
782 }
783
784 impl TryFrom<::std::string::String> for #buffer_ident {
785 type Error = #error<::std::string::String>;
786
787 fn try_from(input: ::std::string::String) -> Result<#buffer_ident, #error<::std::string::String>> {
788 let bytes = input.into_bytes();
789 #buffer_ident::new(bytes).map_err(|#error(bytes)| unsafe {
790 #error(::std::string::String::from_utf8_unchecked(bytes))
791 })
792 }
793 }
794
795 impl From<#buffer_ident> for String {
796 fn from(value: #buffer_ident) -> String {
797 value.into_string()
798 }
799 }
800 })
801 }
802
803 if T::UNICODE || ascii {
804 tokens.extend(quote! {
805 impl ::std::str::FromStr for #buffer_ident {
806 type Err = #error<::std::string::String>;
807
808 fn from_str(s: &str) -> Result<Self, #error<::std::string::String>> {
809 let buffer = s.to_string();
810 buffer.try_into()
811 }
812 }
813 })
814 }
815
816 if contains_empty {
817 tokens.extend(quote! {
818 impl ::core::default::Default for #buffer_ident {
819 fn default() -> Self {
820 unsafe {
821 Self::new_unchecked(::core::default::Default::default())
822 }
823 }
824 }
825 })
826 }
827
828 if !data.options.no_borrow {
829 let as_bytes = T::rust_inner_as_bytes_method().map(|as_bytes| {
830 quote! {
831 pub fn as_bytes(&self) -> &[u8] {
832 self.0.#as_bytes()
833 }
834 }
835 });
836
837 let into_bytes = T::rust_inner_into_bytes_method().map(|into_bytes| {
838 quote! {
839 pub fn into_bytes(self) -> Vec<u8> {
840 self.0.#into_bytes()
841 }
842 }
843 });
844
845 let borrow_bytes = T::rust_inner_as_bytes_method().map(|as_bytes| {
846 quote! {
847 impl ::core::convert::AsRef<[u8]> for #buffer_ident {
848 fn as_ref(&self) -> &[u8] {
849 self.0.#as_bytes()
850 }
851 }
852 }
853 });
854
855 let borrow_ascii = T::rust_inner_as_ascii_method_body().map(|as_ascii| {
856 quote! {
857 impl ::core::convert::AsRef<str> for #buffer_ident {
858 fn as_ref(&self) -> &str {
859 #as_ascii
860 }
861 }
862 }
863 });
864
865 let into_inner = T::rust_into_inner_method();
866
867 tokens.extend(quote! {
868 impl #buffer_ident {
869 pub fn #as_inner(&self) -> &#string_type {
870 &self.0
871 }
872
873 pub fn #into_inner(self) -> #owned_string_type {
874 self.0
875 }
876
877 #as_bytes
878 #into_bytes
879 }
880
881 impl ::core::borrow::Borrow<#string_type> for #buffer_ident {
882 fn borrow(&self) -> &#string_type {
883 &self.0
884 }
885 }
886
887 impl ::core::convert::AsRef<#string_type> for #buffer_ident {
888 fn as_ref(&self) -> &#string_type {
889 &self.0
890 }
891 }
892
893 #borrow_bytes
894 #borrow_ascii
895 });
896 }
897
898 if buffer.derives.debug {
899 tokens.extend(quote! {
900 impl ::core::fmt::Debug for #buffer_ident {
901 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
902 <#ident as ::core::fmt::Debug>::fmt(self.#as_ref(), f)
903 }
904 }
905 });
906 }
907
908 if buffer.derives.display {
909 tokens.extend(quote! {
910 impl ::core::fmt::Display for #buffer_ident {
911 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
912 <#ident as ::core::fmt::Display>::fmt(self.#as_ref(), f)
913 }
914 }
915 });
916 }
917
918 if buffer.derives.partial_eq {
919 tokens.extend(quote! {
920 impl ::core::cmp::PartialEq for #buffer_ident {
921 fn eq(&self, other: &Self) -> bool {
922 <#ident as ::core::cmp::PartialEq>::eq(self.#as_ref(), other.#as_ref())
923 }
924 }
925
926 impl ::core::cmp::PartialEq<#ident> for #buffer_ident {
927 fn eq(&self, other: &#ident) -> bool {
928 <#ident as ::core::cmp::PartialEq>::eq(self.#as_ref(), other)
929 }
930 }
931
932 impl<'a> ::core::cmp::PartialEq<&'a #ident> for #buffer_ident {
933 fn eq(&self, other: &&'a #ident) -> bool {
934 <#ident as ::core::cmp::PartialEq>::eq(self.#as_ref(), *other)
935 }
936 }
937 });
938 }
939
940 if buffer.derives.eq {
941 tokens.extend(quote! {
942 impl ::core::cmp::Eq for #buffer_ident {}
943 });
944 }
945
946 if buffer.derives.partial_ord {
947 if buffer.derives.ord {
948 tokens.extend(quote! {
949 impl ::core::cmp::Ord for #buffer_ident {
950 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
951 <#ident as ::core::cmp::Ord>::cmp(self.#as_ref(), other.#as_ref())
952 }
953 }
954
955 impl ::core::cmp::PartialOrd for #buffer_ident {
956 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
957 Some(<#buffer_ident as ::core::cmp::Ord>::cmp(self, other))
958 }
959 }
960 });
961 } else {
962 tokens.extend(quote! {
963 impl ::core::cmp::PartialOrd for #buffer_ident {
964 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
965 <#ident as ::core::cmp::PartialOrd>::partial_cmp(self.#as_ref(), other.#as_ref())
966 }
967 }
968 });
969 }
970
971 tokens.extend(quote! {
972 impl ::core::cmp::PartialOrd<#ident> for #buffer_ident {
973 fn partial_cmp(&self, other: &#ident) -> Option<::core::cmp::Ordering> {
974 <#ident as ::core::cmp::PartialOrd>::partial_cmp(self.#as_ref(), other)
975 }
976 }
977
978 impl<'a> ::core::cmp::PartialOrd<&'a #ident> for #buffer_ident {
979 fn partial_cmp(&self, other: &&'a #ident) -> Option<::core::cmp::Ordering> {
980 <#ident as ::core::cmp::PartialOrd>::partial_cmp(self.#as_ref(), *other)
981 }
982 }
983 });
984
985 if buffer.derives.hash {
986 tokens.extend(quote! {
987 impl ::core::hash::Hash for #buffer_ident {
988 fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
989 <#ident as ::core::hash::Hash>::hash(self.#as_ref(), state)
990 }
991 }
992 });
993 }
994 }
995
996 if data.options.serde {
997 let serialize = if T::UNICODE || ascii {
998 quote! {
999 serializer.serialize_str(self.as_str())
1000 }
1001 } else {
1002 quote! {
1003 serializer.serialize_bytes(self.as_bytes())
1004 }
1005 };
1006
1007 let (visit_str, visit_bytes) = if T::UNICODE {
1008 (
1009 quote! {
1010 #buffer_ident::new(v)
1011 },
1012 quote! {
1013 match ::std::string::String::from_utf8(v) {
1014 Ok(s) => #buffer_ident::new(s).map_err(|#error(s)| #error(s.into_bytes())),
1015 Err(e) => Err(#error(e.into_bytes()))
1016 }
1017 },
1018 )
1019 } else {
1020 (
1021 quote! {
1022 #buffer_ident::new(v.into_bytes()).map_err(|#error(bytes)| unsafe {
1023 #error(::std::string::String::from_utf8_unchecked(bytes))
1024 })
1025 },
1026 quote! {
1027 #buffer_ident::new(v)
1028 },
1029 )
1030 };
1031
1032 let expected = format!("some {ident}");
1033
1034 tokens.extend(quote! {
1035 impl ::serde::Serialize for #buffer_ident {
1036 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1037 where
1038 S: ::serde::Serializer
1039 {
1040 #serialize
1041 }
1042 }
1043
1044 impl<'de> ::serde::Deserialize<'de> for #buffer_ident {
1045 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1046 where
1047 D: ::serde::Deserializer<'de>
1048 {
1049 struct Visitor;
1050
1051 impl<'de> ::serde::de::Visitor<'de> for Visitor {
1052 type Value = #buffer_ident;
1053
1054 fn expecting(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1055 write!(f, #expected)
1056 }
1057
1058 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
1059 where
1060 E: ::serde::de::Error
1061 {
1062 self.visit_string(v.to_string())
1063 }
1064
1065 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
1066 where
1067 E: ::serde::de::Error
1068 {
1069 self.visit_byte_buf(v.to_vec())
1070 }
1071
1072 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
1073 where
1074 E: ::serde::de::Error
1075 {
1076 #visit_str.map_err(|#error(v)| E::invalid_value(::serde::de::Unexpected::Str(&v), &self))
1077 }
1078
1079 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
1080 where
1081 E: ::serde::de::Error
1082 {
1083 #visit_bytes.map_err(|#error(v)| E::invalid_value(::serde::de::Unexpected::Bytes(&v), &self))
1084 }
1085 }
1086
1087 deserializer.deserialize_str(Visitor)
1088 }
1089 }
1090 })
1091 }
1092 }
1093
1094 Ok(tokens)
1095}
1096
1097fn generate_validation_function<T: Token>(automaton: &DetAutomaton<u32, T::Set>) -> TokenStream {
1098 let initial_state = *automaton.initial_state();
1099
1100 let states = automaton.transitions().iter().map(|(q, transitions)| {
1101 let transitions = transitions.iter().map(|(set, target)| {
1102 let set = T::Set::rust_set(set);
1103 quote! {
1104 Some(#set) => #target
1105 }
1106 });
1107
1108 let is_final = automaton.is_final_state(q);
1109
1110 quote! {
1111 #q => match input.next() {
1112 #(#transitions,)*
1113 Some(_) => break false,
1114 None => break #is_final
1115 }
1116 }
1117 });
1118
1119 quote! {
1120 let mut state = #initial_state;
1121 loop {
1122 state = match state {
1123 #(#states,)*
1124 _ => unreachable!()
1125 }
1126 }
1127 }
1128}