internal static ConnectionOptions ParseConnectionOptions()

in MySQL.Data/src/X/XDevAPI/Client.cs [448:522]


    internal static ConnectionOptions ParseConnectionOptions(object connectionOptions)
    {
      DbDoc options;
      try
      {
        options = new DbDoc(connectionOptions);
      }
      catch (Exception ex)
      {
        throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, "JSON"), ex);
      }
      if (options == null
        || options.values.Count == 0)
        throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, connectionOptions));

      ConnectionOptions instance = new ConnectionOptions();
      Type optionType = instance.GetType();
      foreach (var item in options.values)
      {
        PropertyInfo parent = optionType.GetProperty(item.Key,
          BindingFlags.Instance
          | BindingFlags.Public
          | BindingFlags.IgnoreCase);
        if (parent == null)
          throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid, item.Key));

        object target = parent.GetValue(instance);
        if (parent.DeclaringType.IsNested)
        {
          DbDoc children;
          try
          {
            children = new DbDoc(item.Value);
          }
          catch (Exception ex)
          {
            throw new ArgumentException(string.Format(ResourcesX.ClientOptionInvalidValue, item.Key, "JSON"), ex);
          }
          if (children == null
            || children.values.Count == 0)
            throw new ArgumentException(string.Format(ResourcesX.ClientOptionInvalidValue, item.Key, item.Value));
          foreach (var option in children.values)
          {
            var key = parent.PropertyType.GetProperty(option.Key,
              BindingFlags.Instance
              | BindingFlags.Public
              | BindingFlags.IgnoreCase);
            if (key == null)
              throw new ArgumentException(string.Format(ResourcesX.ClientOptionNotValid,
                $"{item.Key}.{option.Key}"));
            try
            {
              key.SetValue(target, option.Value);
            }
            catch (Exception ex)
            {
              object value = option.Value;
              switch (value)
              {
                case MySqlExpression expr:
                  value = ((MySqlExpression)expr).value.Trim();
                  break;
              }
              throw new ArgumentException(string.Format(ResourcesX.ClientOptionInvalidValue,
                $"{item.Key}.{option.Key}",
                value),
                ex);
            }
          }
        }

        parent.SetValue(instance, target);
      }
      return instance;
    }