Returns a preserving copy of [`Config`].
(&self)
| 652 | |
| 653 | /// Returns a preserving copy of [`Config`]. |
| 654 | fn doc(&self) -> toml_edit::DocumentMut { |
| 655 | let mut doc = self.doc.clone(); |
| 656 | |
| 657 | let mut set_value = |key: &str, value: Option<&str>| { |
| 658 | set_opt_value(&mut doc, key, value); |
| 659 | }; |
| 660 | // Intentionally use a destructuring assignment in case the fields change... |
| 661 | let RawConfig { |
| 662 | default_server, |
| 663 | server_configs: old_server_configs, |
| 664 | web_session_token, |
| 665 | spacetimedb_token, |
| 666 | listen_addr, |
| 667 | } = &self.home; |
| 668 | |
| 669 | set_value(DEFAULT_SERVER_KEY, default_server.as_deref()); |
| 670 | set_value(WEB_SESSION_TOKEN_KEY, web_session_token.as_deref()); |
| 671 | set_value(SPACETIMEDB_TOKEN_KEY, spacetimedb_token.as_deref()); |
| 672 | set_value(LISTEN_ADDR_KEY, listen_addr.as_deref()); |
| 673 | |
| 674 | // Short-circuit if there are no servers. |
| 675 | if old_server_configs.is_empty() { |
| 676 | doc.remove(SERVER_CONFIGS_KEY); |
| 677 | return doc; |
| 678 | } |
| 679 | // ... or if there are no server_configs to edit. |
| 680 | let new_server_configs = if let Some(cfg) = doc |
| 681 | .get_mut(SERVER_CONFIGS_KEY) |
| 682 | .and_then(toml_edit::Item::as_array_of_tables_mut) |
| 683 | { |
| 684 | cfg |
| 685 | } else { |
| 686 | doc[SERVER_CONFIGS_KEY] = |
| 687 | toml_edit::Item::ArrayOfTables(old_server_configs.iter().map(ServerConfig::as_table).collect()); |
| 688 | return doc; |
| 689 | }; |
| 690 | |
| 691 | let mut new_configs = self |
| 692 | .home |
| 693 | .server_configs |
| 694 | .iter() |
| 695 | .map(|cfg| (cfg.nick_or_host(), cfg)) |
| 696 | .collect::<HashMap<_, _>>(); |
| 697 | |
| 698 | // Update the existing servers, and remove deleted servers. |
| 699 | // We'll add new servers later. |
| 700 | // We do this somewhat elaborate dance rather than just overwriting the config |
| 701 | // in order to preserve the order and formatting of pre-existing server configs in the file. |
| 702 | let mut new_vec = Vec::with_capacity(new_server_configs.len()); |
| 703 | for old_config in new_server_configs.iter_mut() { |
| 704 | let nick_or_host = old_config |
| 705 | .get(NICKNAME_KEY) |
| 706 | .or_else(|| old_config.get(HOST_KEY)) |
| 707 | .and_then(|v| v.as_str()) |
| 708 | .unwrap(); |
| 709 | |
| 710 | if let Some(new_config) = new_configs.remove(nick_or_host) { |
| 711 | ServerConfig::update_table(old_config, new_config); |