Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TextOutputStream to FileDescriptor? #46

Open
JetForMe opened this issue May 6, 2021 · 4 comments
Open

Add TextOutputStream to FileDescriptor? #46

JetForMe opened this issue May 6, 2021 · 4 comments

Comments

@JetForMe
Copy link

JetForMe commented May 6, 2021

Would it make sense to add TextOutputStream conformance to FileDescriptor to support writing something like this:

print("An error occurred", to: FileDescriptor.standardError)

Hmm, I tried doing this:

print("File exists.", to: &FileDescriptor.standardError)       //  Cannot pass immutable value as inout argument: 'standardError' is a get-only property

extension
FileDescriptor : TextOutputStream
{
    public mutating func write(_ inString: String) {
        _ = try? FileDescriptor.standardError.writeAll(inString.utf8)
    }
}

Perhaps those would be better as public static members?

@milseman
Copy link
Contributor

milseman commented May 7, 2021

I really like this idea, but I'm concerned that it just doesn't work out in practice. Writes can throw, a file descriptor might not be open for writing, and TextOutputStream is passed inout. Really, I think there needs to be a new/better pattern for streaming textual output than the one we have.

We could also consider throwing overloads of print and dump. Otherwise it might make sense to wait for a file stream concept.

@JetForMe
Copy link
Author

JetForMe commented May 9, 2021

For stderr it seems we could just swallow the throw. What about a constrained version, like print(_:toStandard:[.out|.error]) that doesn't throw? Or I'd be okay with throwing ones, too, but I hate to deal with try?in front of all of those.

What wold a stream concept do?

@milseman
Copy link
Contributor

"Stream concept" would be a solution for System that provides the kind of functionality that FILE * does in C. You can write to it, it gets buffered locally, and it will flush on shutdown (or explicitly). The devil's in the details and how exactly we want to model it (e.g. unique ownership vs shared vs actor).

@GeorgeLyon
Copy link
Contributor

In one of my project I faced a similar predicament where I wanted something to act as a TextOutputStream, but possibly throw (and be async). The solution I arrived at was to have a withTextOutputStream method like so:

public func withTextOutputStream(_ body: (inout TextOutputStream) -> Void) async throws {
  …
}

https://github.com/GeorgeLyon/Shwift/blob/f80750153de7ef28accca34d53d30bda95b8329b/Sources/Shell/Builtins.swift#L215-L220

It is a little verbose, but a similar solution might work well for FileDescriptor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants