From 185789c9d5ef5549f95a38eea3c5783e30ec3672 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Sat, 18 Mar 2023 23:09:21 +0300 Subject: [PATCH] Chore: Make stuff work --- src/config/config_type.v | 12 ++-- src/config/configs.v | 52 ++++++++++++------ src/config/mapping.v | 73 +++++++++++++++++++++++++ src/config/mapping/mapping.v | 54 ------------------ src/config/{mapping => }/mappings.v | 22 ++++---- src/config/{mapping => }/openttd.cfg | 0 src/config/{mapping => }/transformers.v | 2 +- src/main.v | 52 +++++++++++++++++- 8 files changed, 176 insertions(+), 91 deletions(-) create mode 100644 src/config/mapping.v delete mode 100644 src/config/mapping/mapping.v rename src/config/{mapping => }/mappings.v (72%) rename src/config/{mapping => }/openttd.cfg (100%) rename src/config/{mapping => }/transformers.v (94%) diff --git a/src/config/config_type.v b/src/config/config_type.v index adbecff..fd2be71 100644 --- a/src/config/config_type.v +++ b/src/config/config_type.v @@ -1,19 +1,17 @@ module config -import config.mapping - pub enum ConfigType { openttd private secrets // Other config files are not handled by this tool - // because they are not useful for dedicated servers. + // because they are not useful for dedicated servers. } -fn (ct ConfigType) mapping() mapping.Mapping { +pub fn (ct ConfigType) mapping() Mapping { return match ct { - .openttd { mapping.openttd_config } - .private { mapping.private_config } - .secrets { mapping.secrets_config } + .openttd { openttd_config_mapping } + .secrets { secrets_config_mapping } + .private { private_config_mapping } } } diff --git a/src/config/configs.v b/src/config/configs.v index 5e2a4a0..d401762 100644 --- a/src/config/configs.v +++ b/src/config/configs.v @@ -1,6 +1,23 @@ module config import strings +import toml + +fn nested_string_map_to_toml(m map[string]map[string]string) string { + mut toml_string := strings.new_builder(12800) + + for section, fields in m { + toml_string.writeln('[${section}]') + + for field, value in fields { + toml_string.writeln('${field} = ${value}') + } + + toml_string.write_rune(`\n`) + } + + return toml_string.str() +} [noinit] pub struct OpenTTDConfig { @@ -9,17 +26,16 @@ pub struct OpenTTDConfig { } pub fn (oc OpenTTDConfig) str() string { - mut config_string := strings.new_builder(12800) + return nested_string_map_to_toml(oc.content) +} - for section, section_content in oc.content { - config_string.write_string('[${section}]\n') +pub fn managettd_config_from_file(path string, @type ConfigType) !ManageTTDConfig { + config_toml := toml.parse_file(path)! - for field, value in section_content { - config_string.write_string('${field} = ${value}\n') - } + return ManageTTDConfig{ + content: config_toml.reflect[map[string]map[string]string]() + @type: @type } - - return config_string.str() } pub struct ManageTTDConfig { @@ -27,16 +43,20 @@ pub struct ManageTTDConfig { @type ConfigType } +pub fn (mc ManageTTDConfig) str() string { + return nested_string_map_to_toml(mc.content) +} + // TODO: validate values. pub fn (mc ManageTTDConfig) validate() ! { mapping := mc.@type.mapping() - for section, section_content in mc.content { + for section, fields in mc.content { if section !in mapping { return error('Invalid section: ${section}') } - for field, _ in section_content { + for field, _ in fields { if field !in mapping[section] { return error('Invalid key: ${field}') } @@ -49,20 +69,20 @@ pub fn (mc ManageTTDConfig) to_openttd_config() !OpenTTDConfig { mapping := mc.@type.mapping() - mut openttd_config := map[string]map[string]string{} + mut config := map[string]map[string]string{} - for section, section_content in mc.content { - section_mapping := mapping[section] + for section, fields in mc.content { + section_mapping := mapping[section].clone() - for field, value in section_content { + for field, value in fields { key_mapping := section_mapping[field] - openttd_config[key_mapping.section()][key_mapping.field()] = key_mapping.transform(value) + config[key_mapping.section()][key_mapping.field()] = key_mapping.transform(value) } } return OpenTTDConfig{ - content: openttd_config + content: config @type: mc.@type } } diff --git a/src/config/mapping.v b/src/config/mapping.v new file mode 100644 index 0000000..da0d484 --- /dev/null +++ b/src/config/mapping.v @@ -0,0 +1,73 @@ +module config + +import strings + +pub type Mapping = map[string]map[string]Map + +pub fn (m Mapping) str() string { + mut mapping_string := strings.new_builder(12800) + + for section, fields in m { + mapping_string.writeln('[${section}]') + + for field, field_value in fields { + mapping_string.writeln('${field} = ${field_value.transformed_default_value()}}') + } + + mapping_string.write_rune(`\n`) + } + + return mapping_string.str() +} + +pub fn (m Mapping) to_openttd_config(@type ConfigType) OpenTTDConfig { + return m.to_managettd_config(@type).to_openttd_config() or { panic('unreachable') } +} + +pub fn (m Mapping) to_managettd_config(@type ConfigType) ManageTTDConfig { + mut config_map := map[string]map[string]string{} + + for section, fields in m { + config_map[section] = map[string]string{} + + for field, field_value in fields { + config_map[section][field] = field_value.transformed_default_value() + } + } + + return ManageTTDConfig{ + content: config_map + @type: @type + } +} + +[noinit] +pub struct Map { + equivalent []string [required] + documentation string [required] + default_value string [required] + transform fn (string) string = fn (s string) string { + return s + } +} + +pub fn (m Map) str() string { + comment := '; ' + m.documentation.split_into_lines().join('; ') + + field := m.field() + value := m.transformed_default_value() + + return '${comment}\n${field} = ${value}' +} + +pub fn (m Map) section() string { + return m.equivalent[0] +} + +pub fn (m Map) field() string { + return m.equivalent[1] +} + +pub fn (m Map) transformed_default_value() string { + return m.transform(m.default_value) +} diff --git a/src/config/mapping/mapping.v b/src/config/mapping/mapping.v deleted file mode 100644 index 3f18c8e..0000000 --- a/src/config/mapping/mapping.v +++ /dev/null @@ -1,54 +0,0 @@ -module mapping - -import config - -pub type Mapping = map[string]map[string]Map - -pub fn (m Mapping) to_managettd_config() config.ManageTTDConfig { - mut config_map := map[string]map[string]string{} - - for section, fields in m { - config_map[section] = map[string]string{} - - for field, map in fields { - config_map[section][field] = map.transformed_default_value() - } - } - - return config.ManageTTDConfig{ - content: config_map - @type: // TODO - } -} - -[noinit] -pub struct Map { - equivalent []string [required] - documentation string [required] - default_value string [required] -pub: - transform fn (string) string = fn (s string) string { - return s - } -} - -pub fn (m Map) section() string { - return m.equivalent[0] -} - -pub fn (m Map) field() string { - return m.equivalent[1] -} - -pub fn (m Map) transformed_default_value() string { - return m.transform(m.default_value) -} - -pub fn (m Map) str() string { - comment := '; ' + m.documentation.split_into_lines().join('; ') - - field := m.field() - value := m.transformed_default_value() - - return '${comment}\n${field} = ${value}' -} diff --git a/src/config/mapping/mappings.v b/src/config/mappings.v similarity index 72% rename from src/config/mapping/mappings.v rename to src/config/mappings.v index 24eade8..30f8a9d 100644 --- a/src/config/mapping/mappings.v +++ b/src/config/mappings.v @@ -1,33 +1,33 @@ -module mapping +module config -pub const openttd_config = Mapping({ +pub const openttd_config_mapping = Mapping({ 'ratelimits': { 'maximum_initialization_time': Map{ - equivalent: 'network.max_init_time' + equivalent: ['network', 'max_init_time'] documentation: 'The time the client has to initialize the game in seconds.' default_value: '5' transform: seconds_to_ticks } 'maximum_join_time': Map{ - equivalent: 'network.max_join_time' + equivalent: ['network', 'max_join_time'] documentation: 'The time the client has to join the server in seconds.' default_value: '20' transform: seconds_to_ticks } 'maximum_download_time': Map{ - equivalent: 'network.max_download_time' + equivalent: ['network', 'max_download_time'] documentation: 'The time the client has to download the map in seconds.' default_value: '300' transform: seconds_to_ticks } 'maximum_password_time': Map{ - equivalent: 'network.max_password_time' + equivalent: ['network', 'max_password_time'] documentation: 'The time the client has to enter the server password in seconds.' default_value: '600' transform: seconds_to_ticks } 'maximum_lag_time': Map{ - equivalent: 'network.max_lag_time' + equivalent: ['network', 'max_lag_time'] documentation: 'The time the client can lag behind the server in seconds.' default_value: '20' transform: seconds_to_ticks @@ -35,7 +35,7 @@ pub const openttd_config = Mapping({ } 'server': { 'is_public': Map{ - equivalent: 'network.server_game_type' + equivalent: ['network', 'server_game_type'] documentation: 'Whether if the server is public. True means the server can be joined from the server list.' default_value: 'true' transform: boolean_to_custom_value(['private', 'public']) @@ -43,7 +43,7 @@ pub const openttd_config = Mapping({ } 'autoclean': { 'enabled': Map{ - equivalent: 'network.autoclean_companies' + equivalent: ['network', 'autoclean_companies'] documentation: 'Whether if the server should automatically clean up companies. Other autoclean settings only have effect if this is set to true.' default_value: 'false' @@ -51,6 +51,6 @@ Other autoclean settings only have effect if this is set to true.' } }) -pub const private_config = Mapping{} +pub const private_config_mapping = Mapping(map[string]map[string]Map{}) -pub const secrets_config = Mapping{} +pub const secrets_config_mapping = Mapping(map[string]map[string]Map{}) diff --git a/src/config/mapping/openttd.cfg b/src/config/openttd.cfg similarity index 100% rename from src/config/mapping/openttd.cfg rename to src/config/openttd.cfg diff --git a/src/config/mapping/transformers.v b/src/config/transformers.v similarity index 94% rename from src/config/mapping/transformers.v rename to src/config/transformers.v index 9f088ee..ba3c153 100644 --- a/src/config/mapping/transformers.v +++ b/src/config/transformers.v @@ -1,4 +1,4 @@ -module mapping +module config fn seconds_to_ticks(s string) string { return (s.int() * 1000 / 30).str() diff --git a/src/main.v b/src/main.v index 75ffa9f..d4e4412 100644 --- a/src/main.v +++ b/src/main.v @@ -1,5 +1,53 @@ module main -fn main() { - println() +import config +import cli +import os + +fn generate_command() cli.Command { + return cli.Command{ + name: 'convert' + usage: 'convert ' + description: 'Convert a ManageTTD TOML configuration file to an OpenTTD configuration file.' + required_args: 2 + execute: fn (cmd cli.Command) ! { + from := cmd.args[0] + to := cmd.args[1] + + @type := match from { + 'openttd.toml' { + config.ConfigType.openttd + } + 'private.toml' { + config.ConfigType.private + } + 'secrets.toml' { + config.ConfigType.secrets + } + else { + return error('Unknown configuration file type, cannot convert. +Accepted file types are openttd.toml, private.toml and secrets.toml.') + } + } + + managettd_config := config.managettd_config_from_file(from, @type)! + openttd_config_string := managettd_config.to_openttd_config()!.str() + + os.write_file(to, openttd_config_string)! + println('Successfully converted ${from} to ${to}.') + } + } +} + +fn main() { + mut command := cli.Command{ + name: 'managettd' + description: 'OpenTTD server management software.' + version: '0.0.1' + commands: [ + generate_command(), + ] + } + command.setup() + command.parse(os.args) }