parse_items.rs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // -*- coding: utf-8 -*-
  2. //
  3. // Copyright (C) 2024 Michael Büsch <m@bues.ch>
  4. //
  5. // Licensed under the Apache License version 2.0
  6. // or the MIT license, at your option.
  7. // SPDX-License-Identifier: Apache-2.0 OR MIT
  8. use anyhow::{self as ah, format_err as err};
  9. use std::str::FromStr;
  10. pub enum MapItem {
  11. KeyValue(String, String),
  12. KeyValues(String, Vec<String>),
  13. Values(Vec<String>),
  14. }
  15. pub struct Map {
  16. items: Vec<MapItem>,
  17. }
  18. impl FromStr for Map {
  19. type Err = ah::Error;
  20. fn from_str(s: &str) -> Result<Self, Self::Err> {
  21. let mut items = Vec::with_capacity(8);
  22. for item in s.split('/') {
  23. let item = if let Some(idx) = item.find(':') {
  24. let chlen = ':'.len_utf8();
  25. if idx < chlen {
  26. return Err(err!("Invalid item key."));
  27. }
  28. let key = item[..=(idx - chlen)].trim();
  29. if key.is_empty() {
  30. return Err(err!("Invalid item key."));
  31. }
  32. let value = &item[idx + chlen..];
  33. if value.find(',').is_some() {
  34. MapItem::KeyValues(
  35. key.to_string(),
  36. value.split(',').map(|v| v.trim().to_string()).collect(),
  37. )
  38. } else {
  39. MapItem::KeyValue(key.to_string(), value.trim().to_string())
  40. }
  41. } else {
  42. let values = item.split(',');
  43. let values: Vec<String> = values.map(|s| s.trim().to_string()).collect();
  44. MapItem::Values(values)
  45. };
  46. items.push(item);
  47. }
  48. Ok(Map { items })
  49. }
  50. }
  51. impl Map {
  52. pub fn items(&self) -> &[MapItem] {
  53. &self.items
  54. }
  55. }
  56. // vim: ts=4 sw=4 expandtab