///|
/// Optional RON behavior enabled by a document attribute or caller options.
pub(all) struct RonExtensions {
unwrap_newtypes : Bool
implicit_some : Bool
unwrap_variant_newtypes : Bool
explicit_struct_names : Bool
} derive(Eq, Debug)
///|
pub fn RonExtensions::empty() -> RonExtensions {
{
unwrap_newtypes: false,
implicit_some: false,
unwrap_variant_newtypes: false,
explicit_struct_names: false,
}
}
///|
pub fn RonExtensions::add(
self : RonExtensions,
other : RonExtensions,
) -> RonExtensions {
{
unwrap_newtypes: self.unwrap_newtypes || other.unwrap_newtypes,
implicit_some: self.implicit_some || other.implicit_some,
unwrap_variant_newtypes: self.unwrap_variant_newtypes ||
other.unwrap_variant_newtypes,
explicit_struct_names: self.explicit_struct_names ||
other.explicit_struct_names,
}
}
///|
pub fn RonExtensions::is_empty(self : RonExtensions) -> Bool {
!self.unwrap_newtypes &&
!self.implicit_some &&
!self.unwrap_variant_newtypes &&
!self.explicit_struct_names
}
///|
pub fn RonExtensions::from_name(name : String) -> RonExtensions? {
match name {
"unwrap_newtypes" =>
Some({ ..RonExtensions::empty(), unwrap_newtypes: true, })
"implicit_some" => Some({ ..RonExtensions::empty(), implicit_some: true, })
"unwrap_variant_newtypes" =>
Some({ ..RonExtensions::empty(), unwrap_variant_newtypes: true, })
"explicit_struct_names" =>
Some({ ..RonExtensions::empty(), explicit_struct_names: true, })
_ => None
}
}
///|
pub fn RonExtensions::to_attribute(self : RonExtensions) -> String {
if self.is_empty() {
return ""
}
let names = []
if self.unwrap_newtypes {
names.push("unwrap_newtypes")
}
if self.implicit_some {
names.push("implicit_some")
}
if self.unwrap_variant_newtypes {
names.push("unwrap_variant_newtypes")
}
if self.explicit_struct_names {
names.push("explicit_struct_names")
}
"#![enable(" + names.join(", ") + ")]"
}
///|
/// Parsing options and document-level extension defaults.
pub(all) struct RonOptions {
extensions : RonExtensions
max_nesting_depth : Int32
} derive(Eq, Debug)
///|
pub fn RonOptions::default() -> RonOptions {
{ extensions: RonExtensions::empty(), max_nesting_depth: 128, }
}
///|
pub fn RonOptions::with_extension(
self : RonOptions,
extension : RonExtensions,
) -> RonOptions {
{
extensions: self.extensions.add(extension),
max_nesting_depth: self.max_nesting_depth,
}
}
///|
pub fn RonOptions::with_extensions(
self : RonOptions,
extensions : RonExtensions,
) -> RonOptions {
self.with_extension(extensions)
}
///|
pub fn RonOptions::with_max_nesting_depth(
self : RonOptions,
max_nesting_depth : Int32,
) -> RonOptions {
{ extensions: self.extensions, max_nesting_depth, }
}
///|
/// A parsed RON value together with the extensions enabled by its attributes.
pub(all) struct RonDocument {
value : RonValue
extensions : RonExtensions
} derive(Eq, Debug)
///|
fn RonParser::parse_attributes(
self : RonParser,
initial : RonExtensions,
) -> RonExtensions raise RonError {
let mut extensions = initial
self.skip_trivia()
while self.peek() == Some('#') {
let attribute_position = self.position()
self.expect('#')
self.expect('!')
self.expect('[')
self.skip_trivia()
let name = self.parse_identifier()
self.skip_trivia()
match name {
"enable" => extensions = self.parse_enable_attribute(extensions)
"type" | "schema" => self.parse_ignored_attribute(name)
_ => raise UnknownAttribute(attribute_position, name)
}
self.expect(']')
self.skip_trivia()
}
extensions
}
///|
fn RonParser::parse_enable_attribute(
self : RonParser,
initial : RonExtensions,
) -> RonExtensions raise RonError {
let mut extensions = initial
self.expect('(')
self.skip_trivia()
if self.peek() == Some(')') {
self.offset = self.offset + 1
return extensions
}
while true {
let position = self.position()
let name = self.parse_identifier()
match RonExtensions::from_name(name) {
Some(extension) => extensions = extensions.add(extension)
None => raise UnknownExtension(position, name)
}
self.skip_trivia()
match self.peek() {
Some(',') => {
self.offset = self.offset + 1
self.skip_trivia()
if self.peek() == Some(')') {
self.offset = self.offset + 1
break
}
}
Some(')') => {
self.offset = self.offset + 1
break
}
Some(char) => raise self.error_char(char)
None => raise self.error_eof()
}
}
extensions
}
///|
fn RonParser::parse_ignored_attribute(
self : RonParser,
name : String,
) -> Unit raise RonError {
let position = self.position()
self.expect('=')
self.skip_trivia()
match self.peek() {
Some('"') => self.parse_string_literal() |> ignore
Some(char) => raise self.error_char(char)
None => raise self.error_eof()
}
if name.length() == 0 {
raise InvalidAttribute(position, name)
}
}