| ... | @@ -224,6 +224,44 @@ pub fn fromSlice(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZo | ... | @@ -224,6 +224,44 @@ pub fn fromSlice(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZo |
| 224 | return value; | 224 | return value; |
| 225 | } | 225 | } |
| 226 | | 226 | |
| | 227 | test fromSlice { |
| | 228 | const gpa = std.testing.allocator; |
| | 229 | var arena_allocator: ArenaAllocator = .init(gpa); |
| | 230 | defer arena_allocator.deinit(); |
| | 231 | const arena = arena_allocator.allocator(); |
| | 232 | |
| | 233 | const TextureOptions = struct { |
| | 234 | const AddressMode = enum { clamp, reflect, wrap, zero }; |
| | 235 | address_mode: struct { u: AddressMode = .wrap, v: AddressMode = .wrap }, |
| | 236 | mipmaps: bool = true, |
| | 237 | premultiply: bool = true, |
| | 238 | }; |
| | 239 | |
| | 240 | const source = |
| | 241 | \\.{ |
| | 242 | \\ .address_mode = .{ .u = .clamp }, |
| | 243 | \\ .mipmaps = false, |
| | 244 | \\} |
| | 245 | ; |
| | 246 | |
| | 247 | var errors: Errors = .empty; |
| | 248 | const options = fromSlice(TextureOptions, .{ |
| | 249 | .gpa = gpa, |
| | 250 | .arena = arena, |
| | 251 | .source = source, |
| | 252 | .errors = &errors, |
| | 253 | }) catch |err| { |
| | 254 | errors.log("texture_options.zon", err); |
| | 255 | return err; |
| | 256 | }; |
| | 257 | |
| | 258 | try std.testing.expectEqualDeep(TextureOptions{ |
| | 259 | .address_mode = .{ .u = .clamp, .v = .wrap }, |
| | 260 | .mipmaps = false, |
| | 261 | .premultiply = true, |
| | 262 | }, options); |
| | 263 | } |
| | 264 | |
| 227 | /// Like `fromSlice` but the result type may not contain pointers, allowing it to outlive | 265 | /// Like `fromSlice` but the result type may not contain pointers, allowing it to outlive |
| 228 | /// `options.arena`. | 266 | /// `options.arena`. |
| 229 | pub fn fromSliceNoAlloc(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T { | 267 | pub fn fromSliceNoAlloc(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T { |
| ... | @@ -244,6 +282,67 @@ pub fn updateFromSlice( | ... | @@ -244,6 +282,67 @@ pub fn updateFromSlice( |
| 244 | try fromSliceInner(T, value, true, options); | 282 | try fromSliceInner(T, value, true, options); |
| 245 | } | 283 | } |
| 246 | | 284 | |
| | 285 | test updateFromSlice { |
| | 286 | const gpa = std.testing.allocator; |
| | 287 | var arena_allocator: ArenaAllocator = .init(gpa); |
| | 288 | defer arena_allocator.deinit(); |
| | 289 | const arena = arena_allocator.allocator(); |
| | 290 | |
| | 291 | const MyTextEditorConfig = struct { |
| | 292 | indentation: enum { spaces, tabs }, |
| | 293 | columns: []const u16, |
| | 294 | dark_mode: enum { auto, dark, light }, |
| | 295 | theme: []const u8, |
| | 296 | }; |
| | 297 | |
| | 298 | const global_config = |
| | 299 | \\.{ |
| | 300 | \\ .indentation = .spaces, |
| | 301 | \\ .columns = .{ 100 }, |
| | 302 | \\ .dark_mode = .dark, |
| | 303 | \\} |
| | 304 | ; |
| | 305 | const project_config = |
| | 306 | \\.{ |
| | 307 | \\ .indentation = .tabs, |
| | 308 | \\} |
| | 309 | ; |
| | 310 | |
| | 311 | var config: MyTextEditorConfig = .{ |
| | 312 | .indentation = .spaces, |
| | 313 | .columns = &.{}, |
| | 314 | .dark_mode = .auto, |
| | 315 | .theme = "default", |
| | 316 | }; |
| | 317 | |
| | 318 | var errors: Errors = .empty; |
| | 319 | updateFromSlice(MyTextEditorConfig, &config, .{ |
| | 320 | .gpa = gpa, |
| | 321 | .arena = arena, |
| | 322 | .source = global_config, |
| | 323 | .errors = &errors, |
| | 324 | }) catch |err| { |
| | 325 | errors.log("global_config.zon", err); |
| | 326 | return err; |
| | 327 | }; |
| | 328 | updateFromSlice(MyTextEditorConfig, &config, .{ |
| | 329 | .gpa = gpa, |
| | 330 | .arena = arena, |
| | 331 | .source = project_config, |
| | 332 | .errors = &errors, |
| | 333 | }) catch |err| { |
| | 334 | errors.log("project_config.zon", err); |
| | 335 | return err; |
| | 336 | }; |
| | 337 | |
| | 338 | try std.testing.expectEqualDeep(MyTextEditorConfig{ |
| | 339 | .indentation = .tabs, |
| | 340 | .columns = &.{100}, |
| | 341 | .dark_mode = .dark, |
| | 342 | .theme = "default", |
| | 343 | }, config); |
| | 344 | } |
| | 345 | |
| 247 | /// Like `updateFromSlice` but the `T` may not contain pointers, allowing `value` to outlive | 346 | /// Like `updateFromSlice` but the `T` may not contain pointers, allowing `value` to outlive |
| 248 | /// `options.arena`. | 347 | /// `options.arena`. |
| 249 | pub fn updateFromSliceNoAlloc( | 348 | pub fn updateFromSliceNoAlloc( |