From 44154d063dc6ec596969ba3321b203d6494336eb Mon Sep 17 00:00:00 2001 From: Mikko Ahlroth Date: Sun, 19 May 2024 22:52:48 +0300 Subject: [PATCH] Parse metadata from MO file --- src/kielet/mo.gleam | 56 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/kielet/mo.gleam b/src/kielet/mo.gleam index 0730a56..ef40360 100644 --- a/src/kielet/mo.gleam +++ b/src/kielet/mo.gleam @@ -32,6 +32,8 @@ pub type ParseError { OffsetPastEnd(Int) MalformedOffsetTableEntry(BitArray) StringNotUTF8(BitArray) + MetaItemMissing + MetaItemIsNotSingular } pub type Revision { @@ -49,8 +51,16 @@ pub type Header { ) } +pub type MetaData = + Dict(String, String) + pub type Mo { - Mo(endianness: Endianness, header: Header, translations: Translations) + Mo( + endianness: Endianness, + header: Header, + translations: Translations, + metadata: MetaData, + ) } pub fn parse(mo: BitArray) { @@ -62,7 +72,12 @@ pub fn parse(mo: BitArray) { ) use <- bool.guard( header.string_count == 0, - Ok(Mo(endianness: endianness, header: header, translations: dict.new())), + Ok(Mo( + endianness: endianness, + header: header, + translations: dict.new(), + metadata: dict.new(), + )), ) let total_size = bit_array.byte_size(mo) @@ -81,8 +96,14 @@ pub fn parse(mo: BitArray) { ) use translations <- result.try(parse_translations(endianness, header, mo)) + use metadata <- result.try(parse_metadata(translations)) - Ok(Mo(endianness: endianness, header: header, translations: translations)) + Ok(Mo( + endianness: endianness, + header: header, + translations: translations, + metadata: metadata, + )) } fn parse_magic(body: BitArray) { @@ -226,6 +247,35 @@ fn parse_mo_string(mo: BitArray, length: Int, offset: Int) { } } +fn parse_metadata(translations) { + use meta <- result.try( + dict.get(translations, "") + |> result.replace_error(MetaItemMissing), + ) + case meta { + Plural(..) -> Error(MetaItemIsNotSingular) + Singular(content: content, ..) -> { + let metadata = + content + |> string.split("\n") + |> list.map(fn(line) { string.split(line, ":") }) + |> list.map(fn(item) { + case item { + [] -> #("", "") + [key] -> #(string.trim(key), "") + [key, ..rest] -> #( + string.trim(key), + string.trim(string.join(rest, ":")), + ) + } + }) + |> dict.from_list() + + Ok(metadata) + } + } +} + fn le_int_8(int8: BitArray) { case int8 { <> -> Ok(reconstruct_ui8(h, l))