Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed auxiliary method wrapAsCustomStyledYamlNode #26

Open
jonasfj opened this issue Dec 21, 2022 · 7 comments
Open

Proposed auxiliary method wrapAsCustomStyledYamlNode #26

jonasfj opened this issue Dec 21, 2022 · 7 comments
Assignees
Labels
good first issue A good starting issue for contributors (issues with this label will appear in /contribute) type-enhancement A request for a change that isn't a bug

Comments

@jonasfj
Copy link
Member

jonasfj commented Dec 21, 2022

This probably needs some test cases, and I'm sure the code can be improved further!

void main() {
  final doc = YamlEditor('');
  doc.update(
      [],
      wrapAsCustomStyledYamlNode({
        'title': 'Short string as title',
        'description': [
          'Multiple lines with losts of text',
          'that you really makes you want',
          'the YAML to be written with literal strings',
        ].join('\n'),
      }));
  print(doc.toString());
}

YamlNode wrapAsCustomStyledYamlNode(
  Object? value, {
  CollectionStyle Function(Map map, int depth) styleMap = _defaultMapStyle,
  CollectionStyle Function(List list, int depth) styleList = _defaultListStyle,
  ScalarStyle Function(String string, int depth) styleString =
      _defaultStringStyle,
}) {
  YamlNode wrap(Object? value, int depth) {
    if (value is YamlScalar) {
      wrapAsYamlNode(value); // assert valid scalar
      return value;
    } else if (value is YamlList) {
      for (final item in value.nodes) {
        wrapAsYamlNode(item); // assert valid scalar
      }
      return value;
    } else if (value is YamlMap) {
      /// Both [entry.key] and [entry.values] are guaranteed to be [YamlNode]s,
      /// so running this will just assert that they are valid scalars.
      for (final entry in value.nodes.entries) {
        wrapAsYamlNode(entry.key);
        wrapAsYamlNode(entry.value);
      }
      return value;
    } else if (value is Map) {
      return wrapAsYamlNode({
        for (final kv in value.entries)
          wrap(kv.key, depth + 1): wrap(kv.value, depth + 1),
      }, collectionStyle: styleMap(value, depth));
    } else if (value is List) {
      return wrapAsYamlNode({
        for (final v in value) wrap(v, depth + 1),
      }, collectionStyle: styleList(value, depth));
    } else if (value is String) {
      return wrapAsYamlNode(value, scalarStyle: styleString(value, depth));
    } else {
      return wrapAsYamlNode(value);
    }
  }

  return wrap(value, 0);
}

int _sizeOfScalar(dynamic value) => value == null ? 4 : '$value'.length;

CollectionStyle _defaultMapStyle(Map map, int depth) {
  if (map.values.any((value) => value is Map || value is List)) {
    return CollectionStyle.BLOCK;
  }
  final size = map.entries.fold<int>(
    0,
    (sum, entry) => sum + _sizeOfScalar(entry.key) + _sizeOfScalar(entry.value),
  );
  if (size < 80) {
    return CollectionStyle.FLOW;
  }
  return CollectionStyle.BLOCK;
}

CollectionStyle _defaultListStyle(List list, int depth) {
  if (list.any((value) => value is Map || value is List)) {
    return CollectionStyle.BLOCK;
  }
  final size = list.fold<int>(
    0,
    (sum, value) => sum + _sizeOfScalar(value),
  );
  if (size < 80) {
    return CollectionStyle.FLOW;
  }
  return CollectionStyle.BLOCK;
}

ScalarStyle _defaultStringStyle(String string, int depth) {
  if (string.contains('\n')) {
    return ScalarStyle.LITERAL;
  }
  if (string.length > 80) {
    return ScalarStyle.FOLDED;
  }
  if (!string.contains('\'')) {
    if (!string.contains('"')) {
      return ScalarStyle.PLAIN;
    }
    return ScalarStyle.SINGLE_QUOTED;
  }
  return ScalarStyle.DOUBLE_QUOTED;
}
@jonasfj jonasfj added the type-enhancement A request for a change that isn't a bug label Dec 21, 2022
@jonasfj jonasfj added the good first issue A good starting issue for contributors (issues with this label will appear in /contribute) label Dec 21, 2022
@jonasfj
Copy link
Member Author

jonasfj commented Dec 21, 2022

Maybe, there needs to be some logic around depth... I suppose it would be nice with an argument that always goes into flow-mode for a depth higher than some threshold, a reasonable default might be 16 (at that point block-mode becomes pretty sketchy to read, I'm just guessing).

@seifibrahim32
Copy link

I need to try this mr Jonas @jonasfj

@jonasfj
Copy link
Member Author

jonasfj commented Feb 10, 2023

@seifibrahim32, please do give it a try.

I think one of the important aspects is to have proper tests.
Such that we know that the formatting works, and behaves reasonably.

Perhaps, it'd be a good idea to start with #33 (I just filed it, hehe)
But really, adding the functions above is probably not too hard. The hard part is making sure we have tests, so that we're reasonably confident that these things work.

@seifibrahim32
Copy link

Sure i will try to take a look

@seifibrahim32
Copy link

I will take this try please...again, Google Summer of Code took me time for proposal. my apologies.

@jonasfj

@seifibrahim32
Copy link

Let me take a try :))

@seifibrahim32
Copy link

seifibrahim32 commented Apr 18, 2023

Thanks for assignment , let me check the code and I reply you within tomorrow to see how we would make flutter_test :D

Update:
My first approach : Understand wrapAsYamlNode how it works
Then the second approach : Try to use the wrapAsCustomedYamlNode for that.
Then the third add test cases and refactor the code..

So all what I have to do is adding some test cases

@jonasfj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue A good starting issue for contributors (issues with this label will appear in /contribute) type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

2 participants