• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ArkScript-lang / Ark / 11445793250

21 Oct 2024 05:51PM UTC coverage: 76.877% (+0.4%) from 76.499%
11445793250

push

github

SuperFola
refactor(macro): removing useless constructor

5130 of 6673 relevant lines covered (76.88%)

9379.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.03
/src/arkreactor/Builtins/String.cpp
1
#include <Ark/Builtins/Builtins.hpp>
2

3
#include <utility>
4
#include <utf8.hpp>
5
#include <fmt/args.h>
6
#include <fmt/core.h>
7
#include <fmt/format.h>
8

9
#include <Ark/TypeChecker.hpp>
10
#include <Ark/VM/VM.hpp>
11

12
namespace Ark::internal::Builtins::String
13
{
14
    /**
15
     * @name str:format
16
     * @brief Format a String given replacements
17
     * @details https://fmt.dev/latest/syntax.html
18
     * @param format the String to format
19
     * @param values as any argument as you need, of any valid ArkScript type
20
     * =begin
21
     * (str:format "Hello {}, my name is {}" "world" "ArkScript")
22
     * # Hello world, my name is ArkScript
23
     *
24
     * (str:format "Test {} with {{}}" "1")
25
     * # Test 1 with {}
26
     * =end
27
     * @author https://github.com/SuperFola
28
     */
29
    Value format(std::vector<Value>& n, VM* vm)
17✔
30
    {
17✔
31
        if (n.size() < 2 || n[0].valueType() != ValueType::String)
17✔
32
            types::generateError(
1✔
33
                "str:format",
×
34
                { { types::Contract { { types::Typedef("string", ValueType::String),
×
35
                                        types::Typedef("value", ValueType::Any, /* variadic */ true) } } } },
×
36
                n);
×
37

38
        fmt::dynamic_format_arg_store<fmt::format_context> store;
17✔
39

40
        for (auto it = n.begin() + 1, it_end = n.end(); it != it_end; ++it)
36✔
41
        {
42
            if (it->valueType() == ValueType::String)
19✔
43
                store.push_back(it->stringRef());
1✔
44
            else if (it->valueType() == ValueType::Number)
18✔
45
                store.push_back(it->number());
14✔
46
            else if (it->valueType() == ValueType::Nil)
4✔
47
                store.push_back("nil");
1✔
48
            else if (it->valueType() == ValueType::True)
3✔
49
                store.push_back("true");
1✔
50
            else if (it->valueType() == ValueType::False)
2✔
51
                store.push_back("false");
1✔
52
            else
53
                store.push_back(it->toString(*vm));
1✔
54
        }
19✔
55

56
        try
57
        {
58
            return Value(fmt::vformat(n[0].stringRef(), store));
17✔
59
        }
1✔
60
        catch (fmt::format_error& e)
61
        {
62
            throw std::runtime_error(
2✔
63
                fmt::format("str:format: can not format \"{}\" ({} argument{} provided) because of {}",
3✔
64
                            n[0].stringRef(),
1✔
65
                            n.size() - 1,
1✔
66
                            // if we have more than one argument (not counting the string to format), plural form
67
                            n.size() > 2 ? "s" : "",
1✔
68
                            e.what()));
1✔
69
        }
1✔
70
    }
19✔
71

72
    /**
73
     * @name str:find
74
     * @brief Search a substring in a given String
75
     * @details The original String is not modified. Return -1 when not found
76
     * @param string the String to search in
77
     * @param substr the substring to search for
78
     * =begin
79
     * (str:find "hello world" "hello")  # 0
80
     * (str:find "hello world" "aworld")  # -1
81
     * =end
82
     * @author https://github.com/SuperFola
83
     */
84
    Value findSubStr(std::vector<Value>& n, VM* vm [[maybe_unused]])
9✔
85
    {
9✔
86
        if (!types::check(n, ValueType::String, ValueType::String))
9✔
87
            types::generateError(
×
88
                "str:find",
×
89
                { { types::Contract { { types::Typedef("string", ValueType::String), types::Typedef("substr", ValueType::String) } } } },
×
90
                n);
×
91

92
        std::size_t index = n[0].stringRef().find(n[1].stringRef());
9✔
93
        if (index != std::string::npos)
9✔
94
            return Value(static_cast<int>(index));
5✔
95
        return Value(-1);
4✔
96
    }
9✔
97

98
    /**
99
     * @name str:removeAt
100
     * @brief Remove a character from a String given an index
101
     * @details The original String is not modified
102
     * @param string the String to modify
103
     * @param index the index of the character to remove (can be negative to search from the end)
104
     * =begin
105
     * (str:removeAt "hello world" 0)  # "ello world"
106
     * (str:removeAt "hello world" -1)  # "hello worl"
107
     * =end
108
     * @author https://github.com/SuperFola
109
     */
110
    Value removeAtStr(std::vector<Value>& n, VM* vm [[maybe_unused]])
7✔
111
    {
7✔
112
        if (!types::check(n, ValueType::String, ValueType::Number))
7✔
113
            types::generateError(
1✔
114
                "str:removeAt",
×
115
                { { types::Contract { { types::Typedef("string", ValueType::String), types::Typedef("index", ValueType::Number) } } } },
×
116
                n);
×
117

118
        long id = static_cast<long>(n[1].number());
7✔
119
        if (id < 0 || std::cmp_greater_equal(id, n[0].stringRef().size()))
7✔
120
            throw std::runtime_error(fmt::format("str:removeAt: index {} out of range (length: {})", id, n[0].stringRef().size()));
1✔
121

122
        n[0].stringRef().erase(static_cast<std::size_t>(id), 1);
6✔
123
        return n[0];
6✔
124
    }
8✔
125

126
    /**
127
     * @name str:ord
128
     * @brief Get the ordinal of a given character
129
     * @param char a String with a single UTF8 character
130
     * =begin
131
     * (str:ord "h")  # 104
132
     * (str:ord "Ô")  # 212
133
     * =end
134
     * @author https://github.com/SuperFola
135
     */
136
    Value ord(std::vector<Value>& n, VM* vm [[maybe_unused]])
2✔
137
    {
2✔
138
        if (!types::check(n, ValueType::String))
2✔
139
            types::generateError(
×
140
                "str:ord",
×
141
                { { types::Contract { { types::Typedef("string", ValueType::String) } } } },
×
142
                n);
×
143

144
        return Value(utf8::codepoint(n[0].stringRef().c_str()));
2✔
145
    }
×
146

147
    /**
148
     * @name str:chr
149
     * @brief Create a character from an UTF8 codepoint
150
     * @param codepoint an UTF8 codepoint (Number)
151
     * =begin
152
     * (str:chr 104)  # "h"
153
     * (str:chr 212)  # "Ô"
154
     * =end
155
     * @author https://github.com/SuperFola
156
     */
157
    Value chr(std::vector<Value>& n, VM* vm [[maybe_unused]])
2✔
158
    {
2✔
159
        if (!types::check(n, ValueType::Number))
2✔
160
            types::generateError(
×
161
                "str:chr",
×
162
                { { types::Contract { { types::Typedef("codepoint", ValueType::Number) } } } },
×
163
                n);
×
164

165
        std::array<char, 5> utf8 {};
2✔
166
        utf8::codepointToUtf8(static_cast<int>(n[0].number()), utf8.data());
2✔
167
        return Value(std::string(utf8.data()));
2✔
168
    }
2✔
169
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc