Skip to main content

nwnrs_nwscript/
source.rs

1use std::{collections::HashMap, error::Error, fmt};
2
3use nwnrs_types::resman::prelude::*;
4use serde::{Deserialize, Serialize};
5
6use crate::CompilerErrorCode;
7
8/// The built-in NWN resource type used for `NWScript` source files.
9pub const NW_SCRIPT_SOURCE_RES_TYPE: ResType = ResType(2009);
10
11/// The upstream default include-depth limit.
12pub const DEFAULT_MAX_INCLUDE_DEPTH: usize = 16;
13
14/// Errors returned while resolving or loading source files.
15#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SourceError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            SourceError::Resolver(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Resolver", &__self_0),
            SourceError::Compiler {
                code: __self_0, script_name: __self_1, message: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Compiler", "code", __self_0, "script_name", __self_1,
                    "message", &__self_2),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SourceError {
    #[inline]
    fn clone(&self) -> SourceError {
        match self {
            SourceError::Resolver(__self_0) =>
                SourceError::Resolver(::core::clone::Clone::clone(__self_0)),
            SourceError::Compiler {
                code: __self_0, script_name: __self_1, message: __self_2 } =>
                SourceError::Compiler {
                    code: ::core::clone::Clone::clone(__self_0),
                    script_name: ::core::clone::Clone::clone(__self_1),
                    message: ::core::clone::Clone::clone(__self_2),
                },
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for SourceError {
    #[inline]
    fn eq(&self, other: &SourceError) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (SourceError::Resolver(__self_0),
                    SourceError::Resolver(__arg1_0)) => __self_0 == __arg1_0,
                (SourceError::Compiler {
                    code: __self_0, script_name: __self_1, message: __self_2 },
                    SourceError::Compiler {
                    code: __arg1_0, script_name: __arg1_1, message: __arg1_2 })
                    =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SourceError {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<String>;
        let _: ::core::cmp::AssertParamIsEq<CompilerErrorCode>;
    }
}Eq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SourceError {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    SourceError::Resolver(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "SourceError", 0u32, "Resolver", __field0),
                    SourceError::Compiler {
                        ref code, ref script_name, ref message } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "SourceError", 1u32, "Compiler", 0 + 1 + 1 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "code", code)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "script_name", script_name)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "message", message)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SourceError {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 2")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Resolver" => _serde::__private228::Ok(__Field::__field0),
                            "Compiler" => _serde::__private228::Ok(__Field::__field1),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Resolver" => _serde::__private228::Ok(__Field::__field0),
                            b"Compiler" => _serde::__private228::Ok(__Field::__field1),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SourceError>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SourceError;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum SourceError")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<String>(__variant),
                                    SourceError::Resolver),
                            (__Field::__field1, __variant) => {
                                #[allow(non_camel_case_types)]
                                #[doc(hidden)]
                                enum __Field { __field0, __field1, __field2, __ignore, }
                                #[doc(hidden)]
                                struct __FieldVisitor;
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                                    type Value = __Field;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "field identifier")
                                    }
                                    fn visit_u64<__E>(self, __value: u64)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            0u64 => _serde::__private228::Ok(__Field::__field0),
                                            1u64 => _serde::__private228::Ok(__Field::__field1),
                                            2u64 => _serde::__private228::Ok(__Field::__field2),
                                            _ => _serde::__private228::Ok(__Field::__ignore),
                                        }
                                    }
                                    fn visit_str<__E>(self, __value: &str)
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            "code" => _serde::__private228::Ok(__Field::__field0),
                                            "script_name" =>
                                                _serde::__private228::Ok(__Field::__field1),
                                            "message" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                    fn visit_bytes<__E>(self, __value: &[u8])
                                        -> _serde::__private228::Result<Self::Value, __E> where
                                        __E: _serde::de::Error {
                                        match __value {
                                            b"code" => _serde::__private228::Ok(__Field::__field0),
                                            b"script_name" =>
                                                _serde::__private228::Ok(__Field::__field1),
                                            b"message" => _serde::__private228::Ok(__Field::__field2),
                                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                                        }
                                    }
                                }
                                #[automatically_derived]
                                impl<'de> _serde::Deserialize<'de> for __Field {
                                    #[inline]
                                    fn deserialize<__D>(__deserializer: __D)
                                        -> _serde::__private228::Result<Self, __D::Error> where
                                        __D: _serde::Deserializer<'de> {
                                        _serde::Deserializer::deserialize_identifier(__deserializer,
                                            __FieldVisitor)
                                    }
                                }
                                #[doc(hidden)]
                                struct __Visitor<'de> {
                                    marker: _serde::__private228::PhantomData<SourceError>,
                                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                                }
                                #[automatically_derived]
                                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                                    type Value = SourceError;
                                    fn expecting(&self,
                                        __formatter: &mut _serde::__private228::Formatter)
                                        -> _serde::__private228::fmt::Result {
                                        _serde::__private228::Formatter::write_str(__formatter,
                                            "struct variant SourceError::Compiler")
                                    }
                                    #[inline]
                                    fn visit_seq<__A>(self, mut __seq: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::SeqAccess<'de> {
                                        let __field0 =
                                            match _serde::de::SeqAccess::next_element::<CompilerErrorCode>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                                &"struct variant SourceError::Compiler with 3 elements")),
                                            };
                                        let __field1 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                                &"struct variant SourceError::Compiler with 3 elements")),
                                            };
                                        let __field2 =
                                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                                {
                                                _serde::__private228::Some(__value) => __value,
                                                _serde::__private228::None =>
                                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                                &"struct variant SourceError::Compiler with 3 elements")),
                                            };
                                        _serde::__private228::Ok(SourceError::Compiler {
                                                code: __field0,
                                                script_name: __field1,
                                                message: __field2,
                                            })
                                    }
                                    #[inline]
                                    fn visit_map<__A>(self, mut __map: __A)
                                        -> _serde::__private228::Result<Self::Value, __A::Error>
                                        where __A: _serde::de::MapAccess<'de> {
                                        let mut __field0:
                                                _serde::__private228::Option<CompilerErrorCode> =
                                            _serde::__private228::None;
                                        let mut __field1: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        let mut __field2: _serde::__private228::Option<String> =
                                            _serde::__private228::None;
                                        while let _serde::__private228::Some(__key) =
                                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                                            match __key {
                                                __Field::__field0 => {
                                                    if _serde::__private228::Option::is_some(&__field0) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("code"));
                                                    }
                                                    __field0 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<CompilerErrorCode>(&mut __map)?);
                                                }
                                                __Field::__field1 => {
                                                    if _serde::__private228::Option::is_some(&__field1) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("script_name"));
                                                    }
                                                    __field1 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                __Field::__field2 => {
                                                    if _serde::__private228::Option::is_some(&__field2) {
                                                        return _serde::__private228::Err(<__A::Error as
                                                                        _serde::de::Error>::duplicate_field("message"));
                                                    }
                                                    __field2 =
                                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                                }
                                                _ => {
                                                    let _ =
                                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                                }
                                            }
                                        }
                                        let __field0 =
                                            match __field0 {
                                                _serde::__private228::Some(__field0) => __field0,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("code")?,
                                            };
                                        let __field1 =
                                            match __field1 {
                                                _serde::__private228::Some(__field1) => __field1,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("script_name")?,
                                            };
                                        let __field2 =
                                            match __field2 {
                                                _serde::__private228::Some(__field2) => __field2,
                                                _serde::__private228::None =>
                                                    _serde::__private228::de::missing_field("message")?,
                                            };
                                        _serde::__private228::Ok(SourceError::Compiler {
                                                code: __field0,
                                                script_name: __field1,
                                                message: __field2,
                                            })
                                    }
                                }
                                #[doc(hidden)]
                                const FIELDS: &'static [&'static str] =
                                    &["code", "script_name", "message"];
                                _serde::de::VariantAccess::struct_variant(__variant, FIELDS,
                                    __Visitor {
                                        marker: _serde::__private228::PhantomData::<SourceError>,
                                        lifetime: _serde::__private228::PhantomData,
                                    })
                            }
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Resolver", "Compiler"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "SourceError", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SourceError>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
16pub enum SourceError {
17    /// The source resolver itself failed.
18    Resolver(String),
19    /// The requested source file could not be loaded or violated a compiler
20    /// rule.
21    Compiler {
22        /// Stable upstream-aligned compiler error code.
23        code:        CompilerErrorCode,
24        /// Logical script name associated with the failure.
25        script_name: String,
26        /// Human-readable error message.
27        message:     String,
28    },
29}
30
31impl SourceError {
32    /// Returns the upstream compiler error code when this is a compiler
33    /// failure.
34    #[must_use]
35    pub fn code(&self) -> Option<CompilerErrorCode> {
36        match self {
37            Self::Resolver(_) => None,
38            Self::Compiler {
39                code, ..
40            } => Some(*code),
41        }
42    }
43
44    /// Creates a source resolver error.
45    pub fn resolver(message: impl Into<String>) -> Self {
46        Self::Resolver(message.into())
47    }
48
49    /// Creates a file-not-found error.
50    pub fn file_not_found(script_name: impl Into<String>) -> Self {
51        let script_name = script_name.into();
52        Self::Compiler {
53            code: CompilerErrorCode::FileNotFound,
54            message: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("source file {0:?} was not found",
                script_name))
    })format!("source file {script_name:?} was not found"),
55            script_name,
56        }
57    }
58
59    /// Creates an include-recursive error.
60    pub fn include_recursive(script_name: impl Into<String>) -> Self {
61        let script_name = script_name.into();
62        Self::Compiler {
63            code: CompilerErrorCode::IncludeRecursive,
64            message: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("recursive include detected for {0:?}",
                script_name))
    })format!("recursive include detected for {script_name:?}"),
65            script_name,
66        }
67    }
68
69    /// Creates an include-too-many-levels error.
70    pub fn include_too_many_levels(
71        script_name: impl Into<String>,
72        max_include_depth: usize,
73    ) -> Self {
74        let script_name = script_name.into();
75        Self::Compiler {
76            code: CompilerErrorCode::IncludeTooManyLevels,
77            message: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("include depth exceeded the configured maximum of {0} while loading {1:?}",
                max_include_depth, script_name))
    })format!(
78                "include depth exceeded the configured maximum of {max_include_depth} while \
79                 loading {script_name:?}"
80            ),
81            script_name,
82        }
83    }
84}
85
86impl fmt::Display for SourceError {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        match self {
89            Self::Resolver(message) => f.write_str(message),
90            Self::Compiler {
91                message,
92                code,
93                ..
94            } => f.write_fmt(format_args!("{1} ({0})", code.code(), message))write!(f, "{message} ({})", code.code()),
95        }
96    }
97}
98
99impl Error for SourceError {}
100
101/// Options controlling source loading and include traversal.
102#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SourceLoadOptions {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "SourceLoadOptions", "res_type", &self.res_type,
            "max_include_depth", &&self.max_include_depth)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SourceLoadOptions {
    #[inline]
    fn clone(&self) -> SourceLoadOptions {
        let _: ::core::clone::AssertParamIsClone<ResType>;
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SourceLoadOptions { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for SourceLoadOptions {
    #[inline]
    fn eq(&self, other: &SourceLoadOptions) -> bool {
        self.res_type == other.res_type &&
            self.max_include_depth == other.max_include_depth
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SourceLoadOptions {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<ResType>;
        let _: ::core::cmp::AssertParamIsEq<usize>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for SourceLoadOptions {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.res_type, state);
        ::core::hash::Hash::hash(&self.max_include_depth, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SourceLoadOptions {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SourceLoadOptions", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "res_type", &self.res_type)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "max_include_depth", &self.max_include_depth)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SourceLoadOptions {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "res_type" => _serde::__private228::Ok(__Field::__field0),
                            "max_include_depth" =>
                                _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"res_type" => _serde::__private228::Ok(__Field::__field0),
                            b"max_include_depth" =>
                                _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SourceLoadOptions>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SourceLoadOptions;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct SourceLoadOptions")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<ResType>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SourceLoadOptions with 2 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SourceLoadOptions with 2 elements")),
                            };
                        _serde::__private228::Ok(SourceLoadOptions {
                                res_type: __field0,
                                max_include_depth: __field1,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<ResType> =
                            _serde::__private228::None;
                        let mut __field1: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("res_type"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<ResType>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("max_include_depth"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("res_type")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("max_include_depth")?,
                            };
                        _serde::__private228::Ok(SourceLoadOptions {
                                res_type: __field0,
                                max_include_depth: __field1,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["res_type", "max_include_depth"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SourceLoadOptions", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SourceLoadOptions>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
103pub struct SourceLoadOptions {
104    /// Resource type requested from the source resolver.
105    pub res_type:          ResType,
106    /// Maximum recursive include depth.
107    pub max_include_depth: usize,
108}
109
110impl Default for SourceLoadOptions {
111    fn default() -> Self {
112        Self {
113            res_type:          NW_SCRIPT_SOURCE_RES_TYPE,
114            max_include_depth: DEFAULT_MAX_INCLUDE_DEPTH,
115        }
116    }
117}
118
119/// Identifies one loaded `NWScript` source file within a compilation session.
120#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SourceId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "SourceId",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SourceId {
    #[inline]
    fn clone(&self) -> SourceId {
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SourceId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for SourceId {
    #[inline]
    fn eq(&self, other: &SourceId) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SourceId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for SourceId {
    #[inline]
    fn partial_cmp(&self, other: &SourceId)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for SourceId {
    #[inline]
    fn cmp(&self, other: &SourceId) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for SourceId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SourceId {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "SourceId", &self.0)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SourceId {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SourceId>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SourceId;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "tuple struct SourceId")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private228::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: u32 =
                            <u32 as _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private228::Ok(SourceId(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<u32>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct SourceId with 1 element")),
                            };
                        _serde::__private228::Ok(SourceId(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "SourceId",
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SourceId>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
121pub struct SourceId(u32);
122
123impl SourceId {
124    /// Creates a new source identifier from its stable numeric value.
125    #[must_use]
126    pub const fn new(value: u32) -> Self {
127        Self(value)
128    }
129
130    /// Returns the stable numeric value for this source identifier.
131    #[must_use]
132    pub const fn get(self) -> u32 {
133        self.0
134    }
135}
136
137impl fmt::Display for SourceId {
138    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139        self.0.fmt(f)
140    }
141}
142
143/// A half-open byte span within one source file.
144#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Span {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Span",
            "source_id", &self.source_id, "start", &self.start, "end",
            &&self.end)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Span {
    #[inline]
    fn clone(&self) -> Span {
        let _: ::core::clone::AssertParamIsClone<SourceId>;
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Span { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Span {
    #[inline]
    fn eq(&self, other: &Span) -> bool {
        self.source_id == other.source_id && self.start == other.start &&
            self.end == other.end
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Span {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<SourceId>;
        let _: ::core::cmp::AssertParamIsEq<usize>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Span {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.source_id, state);
        ::core::hash::Hash::hash(&self.start, state);
        ::core::hash::Hash::hash(&self.end, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for Span {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer, "Span",
                            false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "source_id", &self.source_id)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "start", &self.start)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "end", &self.end)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for Span {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "source_id" => _serde::__private228::Ok(__Field::__field0),
                            "start" => _serde::__private228::Ok(__Field::__field1),
                            "end" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"source_id" => _serde::__private228::Ok(__Field::__field0),
                            b"start" => _serde::__private228::Ok(__Field::__field1),
                            b"end" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<Span>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = Span;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct Span")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<SourceId>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct Span with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct Span with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct Span with 3 elements")),
                            };
                        _serde::__private228::Ok(Span {
                                source_id: __field0,
                                start: __field1,
                                end: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<SourceId> =
                            _serde::__private228::None;
                        let mut __field1: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        let mut __field2: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("source_id"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<SourceId>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("start"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("end"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("source_id")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("start")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("end")?,
                            };
                        _serde::__private228::Ok(Span {
                                source_id: __field0,
                                start: __field1,
                                end: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["source_id", "start", "end"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "Span", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<Span>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
145pub struct Span {
146    /// The source file containing this span.
147    pub source_id: SourceId,
148    /// The inclusive starting byte offset.
149    pub start:     usize,
150    /// The exclusive ending byte offset.
151    pub end:       usize,
152}
153
154impl Span {
155    /// Creates a new span.
156    #[must_use]
157    pub const fn new(source_id: SourceId, start: usize, end: usize) -> Self {
158        Self {
159            source_id,
160            start,
161            end,
162        }
163    }
164
165    /// Returns the byte length of this span.
166    #[must_use]
167    pub const fn len(self) -> usize {
168        self.end.saturating_sub(self.start)
169    }
170
171    /// Returns `true` when this span is empty.
172    #[must_use]
173    pub const fn is_empty(self) -> bool {
174        self.start == self.end
175    }
176}
177
178/// A one-based line and column location inside a source file.
179#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SourceLocation {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "SourceLocation", "offset", &self.offset, "line", &self.line,
            "column", &&self.column)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SourceLocation {
    #[inline]
    fn clone(&self) -> SourceLocation {
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SourceLocation { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for SourceLocation {
    #[inline]
    fn eq(&self, other: &SourceLocation) -> bool {
        self.offset == other.offset && self.line == other.line &&
            self.column == other.column
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SourceLocation {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<usize>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for SourceLocation {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.offset, state);
        ::core::hash::Hash::hash(&self.line, state);
        ::core::hash::Hash::hash(&self.column, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SourceLocation {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SourceLocation", false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "offset", &self.offset)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "line", &self.line)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "column", &self.column)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SourceLocation {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "offset" => _serde::__private228::Ok(__Field::__field0),
                            "line" => _serde::__private228::Ok(__Field::__field1),
                            "column" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"offset" => _serde::__private228::Ok(__Field::__field0),
                            b"line" => _serde::__private228::Ok(__Field::__field1),
                            b"column" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SourceLocation>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SourceLocation;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct SourceLocation")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SourceLocation with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SourceLocation with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct SourceLocation with 3 elements")),
                            };
                        _serde::__private228::Ok(SourceLocation {
                                offset: __field0,
                                line: __field1,
                                column: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        let mut __field1: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        let mut __field2: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("offset"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("line"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("column"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("offset")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("line")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("column")?,
                            };
                        _serde::__private228::Ok(SourceLocation {
                                offset: __field0,
                                line: __field1,
                                column: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["offset", "line", "column"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SourceLocation", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SourceLocation>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
180pub struct SourceLocation {
181    /// The absolute byte offset.
182    pub offset: usize,
183    /// The one-based source line.
184    pub line:   usize,
185    /// The one-based source column.
186    pub column: usize,
187}
188
189/// One loaded source file plus its line-start table.
190#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SourceFile {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "SourceFile",
            "id", &self.id, "name", &self.name, "contents", &self.contents,
            "line_starts", &&self.line_starts)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SourceFile {
    #[inline]
    fn clone(&self) -> SourceFile {
        SourceFile {
            id: ::core::clone::Clone::clone(&self.id),
            name: ::core::clone::Clone::clone(&self.name),
            contents: ::core::clone::Clone::clone(&self.contents),
            line_starts: ::core::clone::Clone::clone(&self.line_starts),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for SourceFile {
    #[inline]
    fn eq(&self, other: &SourceFile) -> bool {
        self.id == other.id && self.name == other.name &&
                self.contents == other.contents &&
            self.line_starts == other.line_starts
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SourceFile {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<SourceId>;
        let _: ::core::cmp::AssertParamIsEq<String>;
        let _: ::core::cmp::AssertParamIsEq<Vec<u8>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<usize>>;
    }
}Eq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SourceFile {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SourceFile", false as usize + 1 + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "id", &self.id)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "contents", &self.contents)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "line_starts", &self.line_starts)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SourceFile {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __ignore,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "id" => _serde::__private228::Ok(__Field::__field0),
                            "name" => _serde::__private228::Ok(__Field::__field1),
                            "contents" => _serde::__private228::Ok(__Field::__field2),
                            "line_starts" =>
                                _serde::__private228::Ok(__Field::__field3),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"id" => _serde::__private228::Ok(__Field::__field0),
                            b"name" => _serde::__private228::Ok(__Field::__field1),
                            b"contents" => _serde::__private228::Ok(__Field::__field2),
                            b"line_starts" =>
                                _serde::__private228::Ok(__Field::__field3),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SourceFile>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SourceFile;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct SourceFile")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<SourceId>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SourceFile with 4 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SourceFile with 4 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<Vec<u8>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct SourceFile with 4 elements")),
                            };
                        let __field3 =
                            match _serde::de::SeqAccess::next_element::<Vec<usize>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                &"struct SourceFile with 4 elements")),
                            };
                        _serde::__private228::Ok(SourceFile {
                                id: __field0,
                                name: __field1,
                                contents: __field2,
                                line_starts: __field3,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<SourceId> =
                            _serde::__private228::None;
                        let mut __field1: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        let mut __field2: _serde::__private228::Option<Vec<u8>> =
                            _serde::__private228::None;
                        let mut __field3: _serde::__private228::Option<Vec<usize>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("id"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<SourceId>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("contents"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<u8>>(&mut __map)?);
                                }
                                __Field::__field3 => {
                                    if _serde::__private228::Option::is_some(&__field3) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("line_starts"));
                                    }
                                    __field3 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<usize>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("id")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("name")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("contents")?,
                            };
                        let __field3 =
                            match __field3 {
                                _serde::__private228::Some(__field3) => __field3,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("line_starts")?,
                            };
                        _serde::__private228::Ok(SourceFile {
                                id: __field0,
                                name: __field1,
                                contents: __field2,
                                line_starts: __field3,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["id", "name", "contents", "line_starts"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SourceFile", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SourceFile>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
191pub struct SourceFile {
192    /// Stable identifier used by spans and diagnostics.
193    pub id:       SourceId,
194    /// Logical filename used by diagnostics and include tracking.
195    pub name:     String,
196    /// Full source bytes.
197    pub contents: Vec<u8>,
198    line_starts:  Vec<usize>,
199}
200
201impl SourceFile {
202    /// Creates a source file and precomputes line starts for span lookup.
203    pub fn new(id: SourceId, name: impl Into<String>, contents: impl Into<Vec<u8>>) -> Self {
204        let contents = contents.into();
205        let line_starts = compute_line_starts(&contents);
206        Self {
207            id,
208            name: name.into(),
209            contents,
210            line_starts,
211        }
212    }
213
214    /// Returns the byte length of the source contents.
215    #[must_use]
216    pub fn len(&self) -> usize {
217        self.contents.len()
218    }
219
220    /// Returns `true` when the source file is empty.
221    #[must_use]
222    pub fn is_empty(&self) -> bool {
223        self.contents.is_empty()
224    }
225
226    /// Returns the raw source bytes.
227    #[must_use]
228    pub fn bytes(&self) -> &[u8] {
229        &self.contents
230    }
231
232    /// Returns the source contents as UTF-8 when the file is valid UTF-8.
233    #[must_use]
234    pub fn text(&self) -> Option<&str> {
235        std::str::from_utf8(&self.contents).ok()
236    }
237
238    /// Returns the raw bytes covered by `span` when it belongs to this file.
239    #[must_use]
240    pub fn span_bytes(&self, span: Span) -> Option<&[u8]> {
241        if span.source_id != self.id || span.start > span.end || span.end > self.contents.len() {
242            return None;
243        }
244        self.contents.get(span.start..span.end)
245    }
246
247    /// Returns the text covered by `span` when it belongs to this file.
248    #[must_use]
249    pub fn span_text(&self, span: Span) -> Option<&str> {
250        let bytes = self.span_bytes(span)?;
251        std::str::from_utf8(bytes).ok()
252    }
253
254    /// Resolves a byte offset to a one-based line and column.
255    #[must_use]
256    pub fn location(&self, offset: usize) -> Option<SourceLocation> {
257        if offset > self.contents.len() {
258            return None;
259        }
260
261        let line_index = match self.line_starts.binary_search(&offset) {
262            Ok(index) => index,
263            Err(index) => index.checked_sub(1)?,
264        };
265        let line_start = *self.line_starts.get(line_index)?;
266        Some(SourceLocation {
267            offset,
268            line: line_index + 1,
269            column: offset.saturating_sub(line_start) + 1,
270        })
271    }
272}
273
274/// A collection of loaded source files indexed by both id and normalized name.
275#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SourceMap {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "SourceMap",
            "files", &self.files, "names", &&self.names)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SourceMap {
    #[inline]
    fn clone(&self) -> SourceMap {
        SourceMap {
            files: ::core::clone::Clone::clone(&self.files),
            names: ::core::clone::Clone::clone(&self.names),
        }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for SourceMap {
    #[inline]
    fn default() -> SourceMap {
        SourceMap {
            files: ::core::default::Default::default(),
            names: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for SourceMap {
    #[inline]
    fn eq(&self, other: &SourceMap) -> bool {
        self.files == other.files && self.names == other.names
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SourceMap {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Vec<SourceFile>>;
        let _: ::core::cmp::AssertParamIsEq<HashMap<String, SourceId>>;
    }
}Eq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for SourceMap {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "SourceMap", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "files", &self.files)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "names", &self.names)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for SourceMap {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "files" => _serde::__private228::Ok(__Field::__field0),
                            "names" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"files" => _serde::__private228::Ok(__Field::__field0),
                            b"names" => _serde::__private228::Ok(__Field::__field1),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<SourceMap>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = SourceMap;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct SourceMap")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<Vec<SourceFile>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct SourceMap with 2 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<HashMap<String,
                                            SourceId>>(&mut __seq)? {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct SourceMap with 2 elements")),
                            };
                        _serde::__private228::Ok(SourceMap {
                                files: __field0,
                                names: __field1,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0:
                                _serde::__private228::Option<Vec<SourceFile>> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<HashMap<String, SourceId>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("files"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<SourceFile>>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("names"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<HashMap<String,
                                                        SourceId>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("files")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("names")?,
                            };
                        _serde::__private228::Ok(SourceMap {
                                files: __field0,
                                names: __field1,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] = &["files", "names"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "SourceMap", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<SourceMap>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
276pub struct SourceMap {
277    files: Vec<SourceFile>,
278    names: HashMap<String, SourceId>,
279}
280
281impl SourceMap {
282    /// Creates an empty source map.
283    #[must_use]
284    pub fn new() -> Self {
285        Self::default()
286    }
287
288    /// Returns the next identifier that would be assigned to a new file.
289    #[must_use]
290    pub fn next_id(&self) -> SourceId {
291        let id = u32::try_from(self.files.len()).ok().unwrap_or(u32::MAX);
292        SourceId::new(id)
293    }
294
295    /// Inserts a fully constructed source file.
296    pub fn insert_file(&mut self, file: SourceFile) -> SourceId {
297        let normalized = normalize_script_name(&file.name);
298        self.names.insert(normalized, file.id);
299        let id = file.id;
300        self.files.push(file);
301        id
302    }
303
304    /// Creates and inserts a new source file.
305    pub fn add_file(&mut self, name: impl Into<String>, contents: impl Into<Vec<u8>>) -> SourceId {
306        let id = self.next_id();
307        self.insert_file(SourceFile::new(id, name, contents))
308    }
309
310    /// Returns the file for `id`.
311    #[must_use]
312    pub fn get(&self, id: SourceId) -> Option<&SourceFile> {
313        self.files.get(id.get() as usize)
314    }
315
316    /// Returns the file for `name`, using case-insensitive matching.
317    #[must_use]
318    pub fn get_by_name(&self, name: &str) -> Option<&SourceFile> {
319        let id = self.names.get(&normalize_script_name(name))?;
320        self.get(*id)
321    }
322
323    /// Returns `true` when a file with `name` has already been loaded.
324    #[must_use]
325    pub fn contains_name(&self, name: &str) -> bool {
326        self.names.contains_key(&normalize_script_name(name))
327    }
328
329    /// Returns the number of loaded source files.
330    #[must_use]
331    pub fn len(&self) -> usize {
332        self.files.len()
333    }
334
335    /// Returns `true` when there are no files.
336    #[must_use]
337    pub fn is_empty(&self) -> bool {
338        self.files.is_empty()
339    }
340
341    /// Iterates over loaded source files in insertion order.
342    pub fn iter(&self) -> impl Iterator<Item = &SourceFile> {
343        self.files.iter()
344    }
345}
346
347/// Loads script source text by logical name and resource type.
348pub trait ScriptResolver {
349    /// Returns the source bytes for `script_name`, or `None` when it does not
350    /// exist.
351    ///
352    /// # Errors
353    ///
354    /// Returns [`SourceError`] if the underlying resource lookup fails.
355    fn resolve_script_bytes(
356        &self,
357        script_name: &str,
358        res_type: ResType,
359    ) -> Result<Option<Vec<u8>>, SourceError>;
360
361    /// Returns the source contents for `script_name`, or `None` when it does
362    /// not exist.
363    ///
364    /// # Errors
365    ///
366    /// Returns [`SourceError`] if the underlying resource lookup or UTF-8
367    /// decoding fails.
368    fn resolve_script(
369        &self,
370        script_name: &str,
371        res_type: ResType,
372    ) -> Result<Option<String>, SourceError> {
373        match self.resolve_script_bytes(script_name, res_type)? {
374            Some(bytes) => String::from_utf8(bytes).map(Some).map_err(|error| {
375                SourceError::resolver(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("source file is not valid UTF-8: {0}",
                error))
    })format!("source file is not valid UTF-8: {error}"))
376            }),
377            None => Ok(None),
378        }
379    }
380}
381
382/// An in-memory script resolver used for tests and fixture loading.
383#[derive(#[automatically_derived]
impl ::core::fmt::Debug for InMemoryScriptResolver {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "InMemoryScriptResolver", "sources", &&self.sources)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for InMemoryScriptResolver {
    #[inline]
    fn clone(&self) -> InMemoryScriptResolver {
        InMemoryScriptResolver {
            sources: ::core::clone::Clone::clone(&self.sources),
        }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for InMemoryScriptResolver {
    #[inline]
    fn default() -> InMemoryScriptResolver {
        InMemoryScriptResolver {
            sources: ::core::default::Default::default(),
        }
    }
}Default)]
384pub struct InMemoryScriptResolver {
385    sources: HashMap<(ResType, String), Vec<u8>>,
386}
387
388impl InMemoryScriptResolver {
389    /// Creates an empty in-memory resolver.
390    #[must_use]
391    pub fn new() -> Self {
392        Self::default()
393    }
394
395    /// Inserts one source file for an arbitrary resource type.
396    pub fn insert(
397        &mut self,
398        script_name: impl Into<String>,
399        res_type: ResType,
400        contents: impl Into<Vec<u8>>,
401    ) {
402        self.sources.insert(
403            (res_type, normalize_script_name(&script_name.into())),
404            contents.into(),
405        );
406    }
407
408    /// Inserts one standard `.nss` source file.
409    pub fn insert_source(&mut self, script_name: impl Into<String>, contents: impl Into<Vec<u8>>) {
410        self.insert(script_name, NW_SCRIPT_SOURCE_RES_TYPE, contents);
411    }
412}
413
414impl ScriptResolver for InMemoryScriptResolver {
415    fn resolve_script_bytes(
416        &self,
417        script_name: &str,
418        res_type: ResType,
419    ) -> Result<Option<Vec<u8>>, SourceError> {
420        Ok(self
421            .sources
422            .get(&(res_type, normalize_script_name(script_name)))
423            .cloned())
424    }
425
426    fn resolve_script(
427        &self,
428        script_name: &str,
429        res_type: ResType,
430    ) -> Result<Option<String>, SourceError> {
431        match self.resolve_script_bytes(script_name, res_type)? {
432            Some(bytes) => String::from_utf8(bytes).map(Some).map_err(|error| {
433                SourceError::resolver(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("source file is not valid UTF-8: {0}",
                error))
    })format!("source file is not valid UTF-8: {error}"))
434            }),
435            None => Ok(None),
436        }
437    }
438}
439
440pub(crate) fn normalize_script_name(input: &str) -> String {
441    input.to_ascii_lowercase()
442}
443
444fn compute_line_starts(bytes: &[u8]) -> Vec<usize> {
445    let mut starts = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [0]))vec![0];
446    let mut index = 0;
447    while index < bytes.len() {
448        match bytes.get(index) {
449            Some(b'\n') => {
450                starts.push(index + 1);
451                index += 1;
452            }
453            Some(b'\r') => {
454                if bytes.get(index + 1) == Some(&b'\n') {
455                    starts.push(index + 2);
456                    index += 2;
457                } else {
458                    starts.push(index + 1);
459                    index += 1;
460                }
461            }
462            _ => index += 1,
463        }
464    }
465    starts
466}
467
468#[cfg(test)]
469mod tests {
470    use nwnrs_types::resman::prelude::*;
471
472    use super::{
473        InMemoryScriptResolver, NW_SCRIPT_SOURCE_RES_TYPE, ScriptResolver, SourceError, SourceFile,
474        SourceId, SourceLoadOptions, SourceMap, Span,
475    };
476    use crate::CompilerErrorCode;
477
478    #[test]
479    fn computes_locations_across_mixed_line_endings() {
480        let source = SourceFile::new(SourceId::new(7), "mixed.nss", "a\r\nbc\nd");
481
482        let first = source.location(0);
483        assert_eq!(
484            first.map(|location| (location.line, location.column)),
485            Some((1, 1))
486        );
487
488        let second = source.location(3);
489        assert_eq!(
490            second.map(|location| (location.line, location.column)),
491            Some((2, 1))
492        );
493
494        let third = source.location(6);
495        assert_eq!(
496            third.map(|location| (location.line, location.column)),
497            Some((3, 1))
498        );
499    }
500
501    #[test]
502    fn returns_span_text_for_same_source_file() {
503        let source = SourceFile::new(SourceId::new(1), "test.nss", "void main()");
504        let span = Span::new(source.id, 5, 9);
505
506        assert_eq!(source.span_text(span), Some("main"));
507    }
508
509    #[test]
510    fn source_map_tracks_names_case_insensitively() {
511        let mut sources = SourceMap::new();
512        let source_id = sources.add_file("Test.NSS", "void main() {}");
513
514        assert_eq!(
515            sources.get(source_id).map(|file| file.name.as_str()),
516            Some("Test.NSS")
517        );
518        assert_eq!(
519            sources.get_by_name("test.nss").map(|file| file.id),
520            Some(source_id)
521        );
522        assert!(sources.contains_name("TEST.NSS"));
523    }
524
525    #[test]
526    fn in_memory_resolver_matches_names_case_insensitively() {
527        let mut resolver = InMemoryScriptResolver::new();
528        resolver.insert_source("UTIL", "int X;");
529
530        let resolved = resolver.resolve_script("util", NW_SCRIPT_SOURCE_RES_TYPE);
531        assert_eq!(resolved.ok(), Some(Some("int X;".to_string())));
532    }
533
534    #[test]
535    fn in_memory_resolver_preserves_non_utf8_source_bytes() {
536        let mut resolver = InMemoryScriptResolver::new();
537        resolver.insert_source("BYTES", b"\"a\x93\xff\"".to_vec());
538
539        let resolved = resolver.resolve_script_bytes("bytes", NW_SCRIPT_SOURCE_RES_TYPE);
540        assert_eq!(resolved.ok(), Some(Some(b"\"a\x93\xff\"".to_vec())));
541    }
542
543    #[test]
544    fn source_load_options_default_to_nss_and_upstream_depth() {
545        let options = SourceLoadOptions::default();
546
547        assert_eq!(options.res_type, ResType(2009));
548        assert_eq!(options.max_include_depth, 16);
549    }
550
551    #[test]
552    fn source_error_exposes_upstream_code() {
553        let error = SourceError::file_not_found("missing");
554
555        assert_eq!(error.code(), Some(CompilerErrorCode::FileNotFound));
556    }
557}