#Bringing specified types into global scope?

1 messages · Page 1 of 1 (latest)

viral ginkgo
#

I'm playing with some WinAPI stuff and I'm using some of the types from std.os.windows

I know I can do something like this:

const win32 = std.os.windows;
var some_handle: win32.HANDLE;
// OR
const HANDLE = std.os.windows.HANDLE;
var some_handle: HANDLE;

But it would be nice to do something akin to Rust's:

use std::os::windows::{HANDLE, LPCSTR};

So it's not as verbose.

buoyant cedar
#

that would be cool

#

but it doesn't exist

viral ginkgo
rocky creek
#

Zig code in its current form is incredibly easy to search through: as soon as you see an identifier foo, you are guaranteed to find it if you just search through the current file for (const|var|fn) foo. The old usingnamespace behaviour removes this guarantee; any way of allowing what it did would implicitly encourage that pattern, which ends up hiding where stuff is coming from, making code harder to read.
Explicit destructuring like you're suggesting - where you have to specify every name - is much less egregious, but also pretty unnecessary. If you're having to reference a lot of stuff from std.os.windows, the normal approach would simply be to alias that namespace to something short: the standard library very often does const w = std.os.windows; at function scope for convenience. In that case, destructuring into actual separate identifiers saves you 2 characters per usage (while also polluting your local namespace with some random unnecessary stuff).

viral ginkgo
# rocky creek Zig code in its current form is incredibly easy to search through: as soon as yo...

I can see how that makes sense under most circumstances, though my current use case is making me question whether that always make sense.

In my case, I want to use some of the existing types and functions in std.os.windows, but there are WinAPI functions I'd like to use that aren't included in the standard library namespaces.

I could use two separate constants eg.

const w = std.os.windows;
const w_extra = @import("windefs.zig") // Additional API fns/types

But technically, they should be just one namespace, they both contain WinAPI definitions.

So what I have to do currently, is re-export the stuff I need from std.os.windows in my windefs.zig file just so I can have everything under a single namespace, which is kind of annoying eg.

// windefs.zig
const w = std.os.windows;
pub const WINAPI = w.WINAPI;
pub extern "kernel32" fn AllocConsole() callconv(WINAPI) win32.BOOL;
// main.zig
const w = @import("windefs.zig");

fn thing() callconv(w.WINAPI) void {
  _ = w.AllocConsole();
}

Maybe I'm just thinking about the problem wrong idk.

#

I would just use zigwin32, but I don't really need the entirety of the WinAPI at my fingertips lol

rocky creek
#

Just do pub usingnamespace std.os.windows; in your windefs.zig

#

Oh wait no I see your issue, it means you have to qualify stuff like WINAPI

#

Since that file is dedicated to WinAPI functions, I'd be happy using the identifier w globally, and then I'd just qualify the names as needed:

const std = @import("std");
const w = std.os.windows;
pub usingnamespace w;

pub extern "kernel32" fn AllocConsole() callconv(w.WINAPI) w.BOOL;
viral ginkgo
#

Ah, I don't think I fully understood what usingnamespace was good for now. That makes the code quite a bit easier to manage, thank you lol.

rocky creek
#

usingnamespace adds to the namespace, but not the scope: so directly accessing an added decl foo doesn't work from within the same scope, but doing @This().foo works, as does e.g. @import("thing.zig").foo from another file

viral ginkgo
#

Follow up question.

Is there a way to scope my additions under one of the child namespaces, something like:

// windefs.zig
const w = std.os.windows;
pub usingnamespace w;

pub const kernel32 = struct {
    pub usingnamespace w.kernel32;
    pub extern "kernel32" fn AllocConsole() callconv(w.WINAPI) w.BOOL;
    pub extern "kernel32" fn FreeConsole() callconv(w.WINAPI) w.BOOL;
};

But not resulting in an ambiguous reference error lol.

rocky creek
#

no, excluding individual decls from a usingnamespace unfortunately isn't possible