Skip to content

Instantly share code, notes, and snippets.

@creativecreatorormaybenot
Last active December 30, 2023 03:32
Show Gist options
  • Save creativecreatorormaybenot/7c57666a53cbf21f2adab08b4ad84ef5 to your computer and use it in GitHub Desktop.
Save creativecreatorormaybenot/7c57666a53cbf21f2adab08b4ad84ef5 to your computer and use it in GitHub Desktop.
Template string implementation: https://stackoverflow.com/a/57231174/6509751
import 'template_string.dart';
main() {
final templateUrl = TemplateString('{host}/api/v3/{container}/{resourceid}');
final params = <String, dynamic>{'host': 'www.api.com', 'container': 'books', 'resourceid': 10};
print(templateUrl.format(params)); // www.api.com/api/v3/books/10
print(TemplateString('no parameters').format({})); // no parameters
print(TemplateString('{only}{parameters}')
.format({'only': 'I see no', 'parameters': ' parameters'})); // I see no parameters
print(TemplateString('{{{still works}').format({'still works': 'in this case'})); // in this case
print(TemplateString('{won\'t break}}}').format({'won\'t break': true})); // true
}
/// This class allows you to create a template, which you can pass parameters to.
/// Parameters will only be inserted into the template using [TemplateString.format]
/// when the key matches some key in the template that has the following format:
/// "{key}"
/// An example string could look like this: "some-api.org/get/{item}?amount={amount}"
/// As a Gist: https://gist.github.com/creativecreatorormaybenot/7c57666a53cbf21f2adab08b4ad84ef5
class TemplateString {
final List<String> fixedComponents;
final Map<int, String> genericComponents;
int totalComponents;
TemplateString(String template)
: fixedComponents = <String>[],
genericComponents = <int, String>{},
totalComponents = 0 {
final List<String> components = template.split('{');
for (String component in components) {
if (component == '') continue; // If the template starts with "{", skip the first element.
final split = component.split('}');
if (split.length != 1) {
// The condition allows for template strings without parameters.
genericComponents[totalComponents] = split.first;
totalComponents++;
}
if (split.last != '') {
fixedComponents.add(split.last);
totalComponents++;
}
}
}
/// If a key in your template is not included in the [params],
/// it will be replaced by `null`.
/// Parameters for "some-api.org/get/{item}?amount={amount}" could
/// look like this: {'item': 42, 'amount': '42'}
/// Redundant entries in [params] are ignored.
String format(Map<String, dynamic> params) {
String result = '';
int fixedComponent = 0;
for (int i = 0; i < totalComponents; i++) {
if (genericComponents.containsKey(i)) {
result += '${params[genericComponents[i]]}';
continue;
}
result += fixedComponents[fixedComponent++];
}
return result;
}
}
@Tahaan
Copy link

Tahaan commented Jul 30, 2019

Nicely done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment