]> git.ipfire.org Git - location/libloc.git/blob - src/lua/country.c
lua: country: Export remaining properties
[location/libloc.git] / src / lua / country.c
1 /*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15 */
16
17 #include <errno.h>
18 #include <string.h>
19 #include <stdlib.h>
20
21 #include <lua.h>
22 #include <lauxlib.h>
23
24 #include <libloc/country.h>
25
26 #include "location.h"
27 #include "country.h"
28
29 typedef struct country {
30 struct loc_country* country;
31 } Country;
32
33 static Country* luaL_checkcountry(lua_State* L, int i) {
34 void* userdata = luaL_checkudata(L, i, "location.Country");
35
36 // Throw an error if the argument doesn't match
37 luaL_argcheck(L, userdata, i, "Country expected");
38
39 return (Country*)userdata;
40 }
41
42 int create_country(lua_State* L, struct loc_country* country) {
43 // Allocate a new object
44 Country* self = (Country*)lua_newuserdata(L, sizeof(*self));
45
46 // Set metatable
47 luaL_setmetatable(L, "location.Country");
48
49 // Store country
50 self->country = loc_country_ref(country);
51
52 return 1;
53 }
54
55 static int Country_new(lua_State* L) {
56 struct loc_country* country = NULL;
57 const char* code = NULL;
58 int r;
59
60 // Fetch the code
61 code = luaL_checkstring(L, 1);
62
63 // Parse the string
64 r = loc_country_new(ctx, &country, code);
65 if (r)
66 return luaL_error(L, "Could not create country %s: %s\n", code, strerror(errno));
67
68 // Return the country
69 r = create_country(L, country);
70 loc_country_unref(country);
71
72 return r;
73 }
74
75 static int Country_gc(lua_State* L) {
76 Country* self = luaL_checkcountry(L, 1);
77
78 // Free country
79 if (self->country) {
80 loc_country_unref(self->country);
81 self->country = NULL;
82 }
83
84 return 0;
85 }
86
87 static int Country_eq(lua_State* L) {
88 Country* self = luaL_checkcountry(L, 1);
89 Country* other = luaL_checkcountry(L, 2);
90
91 // Push comparison result
92 lua_pushboolean(L, loc_country_cmp(self->country, other->country) == 0);
93
94 return 1;
95 }
96
97 // Name
98
99 static int Country_get_name(lua_State* L) {
100 Country* self = luaL_checkcountry(L, 1);
101
102 // Return the code
103 lua_pushstring(L, loc_country_get_name(self->country));
104
105 return 1;
106 }
107
108 // Code
109
110 static int Country_get_code(lua_State* L) {
111 Country* self = luaL_checkcountry(L, 1);
112
113 // Return the code
114 lua_pushstring(L, loc_country_get_code(self->country));
115
116 return 1;
117 }
118
119 // Continent Code
120
121 static int Country_get_continent_code(lua_State* L) {
122 Country* self = luaL_checkcountry(L, 1);
123
124 // Return the code
125 lua_pushstring(L, loc_country_get_continent_code(self->country));
126
127 return 1;
128 }
129
130 static const struct luaL_Reg Country_functions[] = {
131 { "new", Country_new },
132 { "get_code", Country_get_code },
133 { "get_continent_code", Country_get_continent_code },
134 { "get_name", Country_get_name },
135 { "__eq", Country_eq },
136 { "__gc", Country_gc },
137 { "__tostring", Country_get_code },
138 { NULL, NULL },
139 };
140
141 int register_country(lua_State* L) {
142 return register_class(L, "location.Country", Country_functions);
143 }