Replaces the flaky string-search hack that was previously used, and relies on the pull request https://github.com/projectfluent/fluent-rs/pull/373
7X4MEZJUMLYYIBV7ANLADELOZ7I7AJ5CKFAR35CJ2SBZDDVJFZOQC
VQBJBFEXRTJDBH27SVWRBCBFC7OOFOZ3DSMX7PE5BIZQLGHPVDYAC
QFPQZR4K4UZ7R2GQZJG4NYBGVQJVL2ANIKGGTOHAMIRIBQHPSQGAC
2SITVDYW6KANM24QXRHVSBL6S77UHKJLOSOHSUZQBJFL5NAAGQYAC
5TEX4MNUC4LDDRMNEOVCFNUUEZAGUXMKO3OIEQFXWRQKXSHY2NRQC
3NMKD6I57ONAGHEN4PZIAV2KPYESVR4JL3DTWSHXKCMVJBEQ4GIQC
F5LG7WENUUDRSCTDMA4M6BAC5RWTGQO45C4ZEBZDX6FHCTTHBVGQC
C6W7N6N57UCNHEV55HEZ3G7WN2ZOBGMFBB5M5ZPDB2HNNHHTOPBQC
7M4UI3TWQIAA333GQ577HDWDWZPSZKWCYG556L6SBRLB6SZDQYPAC
VZYZRAO4EXCHW2LBVFG5ELSWG5SCNDREMJ6RKQ4EKQGI2T7SD3ZQC
UKFEFT6LSI4K7X6UHQFZYD52DILKXMZMYSO2UYS2FCHNPXIF4BEQC
/// Calculate the byte offset of the serialized
fn source_with_message_offset(&self, id: &str) -> (NamedSource<String>, usize) {
// Find the message position in the AST
let ast_index = self
.syntax_tree
.body
.iter()
.position(|entry| {
if let Entry::Message(message) = entry {
message.id.name == id
} else {
false
}
})
.unwrap();
let options = fluent_syntax::serializer::Options {
// Make sure to include all source code in error snippet, even if marked as "junk"
with_junk: true,
};
// Serialize everything before this message to get the byte offset
let source_before_message = fluent_syntax::serializer::serialize_with_options(
&Resource {
body: self.syntax_tree.body[0..ast_index].to_vec(),
},
options,
);
let byte_offset = source_before_message.len();
let source_after_offset = fluent_syntax::serializer::serialize_with_options(
&Resource {
body: self.syntax_tree.body[ast_index..].to_vec(),
},
options,
);
let source = format!("{source_before_message}{source_after_offset}");
let named_source = NamedSource::new(self.path.to_string_lossy(), source);
(named_source, byte_offset)
}
// fn remove_expression(
// &mut self,
// id: &str,
// derive_context: &derive::Context,
// ) -> Result<syn::Expr, Error> {
// let message = self.messages.remove(id).unwrap();
// let message_context = MessageContext {
// source: &self,
// root_id: id,
// // Any message where this value is `None` shouldn't be accessed directly, see:
// // https://docs.rs/fluent-syntax/latest/fluent_syntax/ast/struct.Attribute.html#example
// pattern: message.value.as_ref().unwrap(),
// derive_context,
// };
// ast::message_body(message_context)
// }
if let Some(unexpected_key) = unexpected_keys.next() {
let (src, message_offset) = source_file.source_with_message_offset(unexpected_key);
// TODO: group all unexpected keys into single error
if let Some((unexpected_key, unexpected_message)) = unexpected_keys.next() {
let source_code = source_file.named_source.clone();
let (source_code, offset) = message_context
.source
.source_with_message_offset(message_context.root_id);
let location = source_code.inner()[offset..]
.find(&format!("${fluent_name}"))
.unwrap()
+ offset;
let source_code = message_context.source.named_source.clone();