Giter Club home page Giter Club logo

ymlz's Introduction

ymlz

Small and convenient YAML parser

Key FeaturesHow To UseSupportContributionLicense

Key Features

  • Simple and straightforward to use thanks to built-in reflections.
  • Just define a struct, load a yml into it, and access your fields.
  • Supports recursive struct.
  • Deinitialization is handled for you, just call deinit() and you are done.
  • Fields are automatically parsed based on field type.
  • Ability to parse fields optionally.

How To Use

Easiest way to use ymlz is to fetch it via zig fetch, make sure to provide it the url of latest released version as the argument.

See an example below.

zig fetch --save https://github.com/pwbh/ymlz/archive/refs/tags/0.1.0.tar.gz

Now in your build.zig we need to import ymlz as a module the following way:

pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{ ... });

    const ymlz = b.dependency("ymlz", .{});
    exe.root_module.addImport("ymlz", ymlz.module("root"));
}

Parsing YAML from file

We can utilize loadFile which expects the absolute path to your YAML file, I will be loading the following YAML file located in the root of my project under the name file.yml:

first: 500
second: -3
name: just testing strings overhere
fourth: 142.241
foods:
  - Apple
  - Orange
  - Strawberry
  - Mango
inner:
  sd: 12
  k: 2
  l: hello world
  another:
    new: 1
    stringed: its just a string

main.zig:

/// Usage
/// zig build run -- ./file.yml
const std = @import("std");

const Ymlz = @import("ymlz").Ymlz;

// Notice how simple it is to define a struct that is one-to-one
// to the yaml file structure
const Tester = struct {
    first: i32,
    second: i64,
    name: []const u8,
    fourth: f32,
    foods: [][]const u8,
    inner: struct {
        sd: i32,
        k: u8,
        l: []const u8,
        another: struct {
            new: f32,
            stringed: []const u8,
        },
    },
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    defer _ = gpa.deinit();

    const args = try std.process.argsAlloc(allocator);
    defer std.process.argsFree(allocator, args);

    if (args.len < 2) {
        return error.NoPathArgument;
    }


    const yml_location = args[1];

    const yml_path = try std.fs.cwd().realpathAlloc(
        allocator,
        yml_location,
    );
    defer allocator.free(yml_path);

    var ymlz = try Ymlz(Tester).init(allocator);
    const result = try ymlz.loadFile(yml_path);
    defer ymlz.deinit(result);

    // We can print and see that all the fields have been loaded
    std.debug.print("Tester: {any}\n", .{result});
    // Lets try accessing the first field and printing it
    std.debug.print("First: {}\n", .{result.first});
    // same goes for the array that we've defined `foods`
    for (result.foods) |food| {
        std.debug.print("{s}", .{food});
    }
}

Parsing YAML from bytes

Parsing YAML file using generic u8 slice for the sake of our example, lets parse a small YAML inlined in to some variable that contains our YAML in []const u8.

const std = @import("std");

const Ymlz = @import("root.zig").Ymlz;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    defer _ = gpa.deinit();

    const yaml_content =
        \\first: 500
        \\second: -3
        \\name: just testing strings overhere # just a comment
        \\fourth: 142.241
        \\# comment in between lines
        \\foods:
        \\  - Apple
        \\  - Orange
        \\  - Strawberry
        \\  - Mango
        \\inner:
        \\  abcd: 12
        \\  k: 2
        \\  l: hello world                 # comment somewhere
        \\  another:
        \\    new: 1
        \\    stringed: its just a string
    ;

    const Experiment = struct {
        first: i32,
        second: i64,
        name: []const u8,
        fourth: f32,
        foods: [][]const u8,
        inner: struct {
            abcd: i32,
            k: u8,
            l: []const u8,
            another: struct {
                new: f32,
                stringed: []const u8,
            },
        },
    };

    var ymlz = try Ymlz(Experiment).init(allocator);
    const result = try ymlz.loadRaw(yaml_content);
    defer ymlz.deinit(result);

    std.debug.print("Experiment.first: {}\n", .{result.first});
}

Parsing by providing a custom std.io.AnyReader

It's possible to pass your own implementation of the std.io.AnyReader interface to ymlz using loadReader which is used internally for both loadFile and loadRaw. See internal implementation for reference.

Contribution

You are more then welcomed to submit a PR, ymlz codebase is still pretty small and it should be relatively simple to get into it, if you have any questions regarding the project or you just need assist starting out, open an issue.

Support

If you find a bug please submit new issue and I will try to address it in my free time. I do however want to note that this project is used in my bigger project, so any bugs I find, I fix without reporting them as an issue, so some issues that may have been reported have beeen fixed without me seeing them.

License

Apache License 2.0. Can be found under the LICENSE.

ymlz's People

Contributors

interrupt avatar pwbh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

ymlz's Issues

typo in README

ymlz/README.md

Line 135 in 615c014

If you find a bug please [submit new issue](https://github.com/pwbh/ymlz/issues/new) and I will try to address it in my free time. I do however want to not that this project is used in my bigger project, so any bugs I find, I fix without reporting them as an issue, so some issues that may have been reported have beeen fixed without me seeing it yet.

Small type in README. want to not -> want to note

Cool project!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.