toasty
toasty
MModular
Created by toasty on 9/14/2024 in #community-showcase
24.5 project updates and shared conda channel
Hello everyone! Instead of bumping a bunch of different community posts for a my few projects, I figured I'd just group them up here. mog (terminal styling): https://discord.com/channels/1087530497313357884/1239277959508922408/1239277959508922408 mist and weave (ANSI coloring/formatting): https://discord.com/channels/1087530497313357884/1250128768866058251/1250128768866058251 gojo (Go stdlib port): https://discord.com/channels/1087530497313357884/1252045387259445278/1252045387259445278 prism (CLI library): https://discord.com/channels/1087530497313357884/1239276796877475921/1239276796877475921 small_time (Morrow datetime library fork), They're all available to install with magic via my conda channel! Try it out with the following steps: 1. Add "https://repo.prefix.dev/mojo-community" to the list of channels in your mojoproject.toml file. 2. Next, add <package name> to your project's dependencies by running magic add <package name>. 3. Finally, run magic install to install in <package name> and its dependencies. You should see the .mojopkg files in $CONDA_PREFIX/lib/mojo/. If you would like to publish your packages to the channel, I can add others as admins for write access. I figure we could have some shared community channels as a stop gap while the packaging features are built out in magic.
2 replies
MModular
Created by toasty on 8/28/2024 in #questions
Usage of mojo test
Is anyone using mojo test to run their unit tests? I’m trying to use it instead defining a test package that’s executed via mojo run. However, it doesn’t work as described in the docs. If my test directory is not a mojo package, I can’t import my package source code to test it. And -I doesn’t resolve the issue either. I figure I’m just missing something here and was hoping someone else could share their repo as an example.
9 replies
MModular
Created by toasty on 8/14/2024 in #community-showcase
Reading from stdin
Hey everyone! Here's a github gist with a struct to read from stdin and a recreation of the Python input function. https://gist.github.com/thatstoasty/20752ad6fb1d97790c208c007792de4b I was working on this snippet for the stdlib a month or two ago, but got held up figuring out how to add some clean tests where we read from stdin. The furthest I got was feeding stdin to one test, but then the subsequent ones failed. Maybe I'll return to it soon, but I figured people might get some use out of this for now 🙂
17 replies
MModular
Created by toasty on 7/31/2024 in #community-showcase
Stump: Bound logger library
Hello all! stump is very much a work in progress, but it's a bound logger library inspired by Python's structlog and Golang's log packages. It works by wrapping structs that adhere to the Logger trait in a BoundLogger which handles formatting and styling the message and context data. The library comes with a few common ones, namely a print logger, stdout logger, and file logger. The print logger is of course, extremely slow. But the STDLogger struct is almost as fast as a standard print that applies no formatting or styling at all. I recently revived it so it's now operational using the latest Mojo nightly. Dict.pop() is still broken, so I had to figure out a workaround. Morrow has also not been updated for a few versions, so there was a regression in datetime formatting as I had to fork it and try updating it myself. The formatting is almost done, but for now only isoformat is in use. https://github.com/thatstoasty/stump/tree/nightly Please feel free to test it out and break it as I'm sure there's a bunch of use cases I did not consider 🫡 I hope the file scope var segfaulting gets fixed soon, so this can actually exist as a .mojopkg instead of having to copy the code into your repo!
1 replies
MModular
Created by toasty on 6/16/2024 in #community-showcase
Gojo: Experiments in porting over Golang stdlib into Mojo
https://github.com/thatstoasty/gojo/tree/main This library is my attempt at porting over some modules and structs from Golang's stdlib. You can find the list below! Most of these topics were new to me when starting the port, so if you find bugs or opportunities for improvement feel free to drop some comments! It's been a good learning opportunity for both Go and Mojo. Modules - bufio - Reader: Buffered io.Reader - Scanner: Scanner interface to read data via tokens. - bytes - Buffer: Buffer backed by UnsafePointer[UInt8]. - Reader: Reader backed by UnsafePointer[UInt8]. - io - Traits: Reader, Writer, Seeker, Closer, ReadWriter, ReadCloser, WriteCloser, ReadWriteCloser, ReadSeeker, ReadSeekCloser, WriteSeeker, ReadWriteSeeker, ReaderFrom, WriterReadFrom, WriterTo, ReaderWriteTo, ReaderAt, WriterAt, ByteReader, ByteScanner, ByteWriter, StringWriter - Reader and Writer wrapper functions. - FileWrapper: FileHandle Wrapper Reader/Writer - STDOUT/STDERR Writer (leveraging libc). - strings - StringBuilder: String builder for fast string concatenation. - Reader: String reader. - fmt - Basic sprintf function. - syscall - External call wrappers for libc functions and types. - net - Socket: Wraps FileDescriptor and implements network specific functions. - FileDescriptor: File Descriptor wrapper that implements io.Writer, io.Reader, and io.Closer. - Dial and Listen interfaces for Socket connections (for TCP only atm). - Socket struct similar to Python's and a simple FileDescriptor struct.
3 replies
MModular
Created by toasty on 6/11/2024 in #community-showcase
Mist and Weave: ANSI Styling and text formatting libraries
Mist mist lets you safely use advanced styling options on the terminal. It offers you convenient methods to colorize and style your output, without you having to deal with all kinds of weird ANSI escape sequences and color conversions. https://github.com/thatstoasty/mist
import mist

fn main():
# ANSI Color Support (0-15)
var style = mist.new_style().foreground(12)
print(style.render(a))

# ANSI256 Color Support (16-255)
style = mist.new_style().foreground(55)
print(style.render(a))

# RGBColor Support (Hex Codes)
style = mist.new_style().foreground(0xc9a0dc)
print(style.render(a))
import mist

fn main():
# ANSI Color Support (0-15)
var style = mist.new_style().foreground(12)
print(style.render(a))

# ANSI256 Color Support (16-255)
style = mist.new_style().foreground(55)
print(style.render(a))

# RGBColor Support (Hex Codes)
style = mist.new_style().foreground(0xc9a0dc)
print(style.render(a))
Weave weave is a collection of (ANSI-sequence aware) text reflow operations & algorithms. Includes text padding, margins, truncation, wrapping, word wrapping, indenting, and dedenting. https://github.com/thatstoasty/weave eg
from weave import indent

fn main() raises:
print(indent("Hello\nWorld\n TEST!", 5))
from weave import indent

fn main() raises:
print(indent("Hello\nWorld\n TEST!", 5))
Hello
World
TEST!
Hello
World
TEST!
Both of these projects are used in mog, but if you need something lightweight to apply some texting coloring/styling or simple ANSI aware formatting, you can use one of these libraries instead.
3 replies
MModular
Created by toasty on 6/2/2024 in #questions
What features or libraries are you waiting for before you start using Mojo in your domain?
Just curious what the community is waiting for before they start using Mojo seriously in their domain. I'm in the Data Eng/Backend/DevOps space and I have a few I'm waiting for. Namely an HTTP client with SSL support and Database drivers to build data services/tooling. As for Mojo features, I'm excited to see file scope code support and better C FFI (for the above libraries). A clean way to call system commands like subprocess would be great too!
11 replies
MModular
Created by toasty on 5/30/2024 in #questions
Is it possible to store a list of References in Struct?
Calling all reference experts! I've seen some conversations lightly touching on the topic but I haven't seen anything concrete. I know I can do something like this:
struct CLI[is_mutable: Bool, lifetime: AnyLifetime[is_mutable].type]():
var commands: List[Reference[Command, is_mutable, lifetime]]
struct CLI[is_mutable: Bool, lifetime: AnyLifetime[is_mutable].type]():
var commands: List[Reference[Command, is_mutable, lifetime]]
But I can't actually add any references to the list, the lifetimes won't match. Is this something that's not possible in Mojo's current state?
10 replies
MModular
Created by toasty on 5/21/2024 in #questions
Is it possible to convert an Int to a String at comp time?
Hey all, I'm trying to make some comp time friendly structs for my project. I'm struggling with converting an int to a string for some string concatenations. str() does not work at comp time. Minimal example to reproduce the error.
fn main() -> None:
alias s = str(1)
fn main() -> None:
alias s = str(1)
14 replies
MModular
Created by toasty on 5/12/2024 in #community-showcase
Mog: Style definitions for nice terminal layouts (inspired by charmbracelet/lipgloss)
Mog https://github.com/thatstoasty/mog/tree/main Style definitions for nice terminal layouts. Built with TUIs in mind. Ported from/Inspired by: https://github.com/charmbracelet/lipgloss/tree/master Mog takes an expressive, declarative approach to terminal rendering. Users familiar with CSS will feel at home with Mog.
import mog

fn main():
var style = mog.new_style() \
.bold(True) \
.foreground(mog.Color("#FAFAFA")) \
.background(mog.Color("#7D56F4")) \
.padding_top(2) \
.padding_left(4) \
.width(22)

print(style.render("Hello, Mojo"))
import mog

fn main():
var style = mog.new_style() \
.bold(True) \
.foreground(mog.Color("#FAFAFA")) \
.background(mog.Color("#7D56F4")) \
.padding_top(2) \
.padding_left(4) \
.width(22)

print(style.render("Hello, Mojo"))
3 replies
MModular
Created by toasty on 5/12/2024 in #community-showcase
Prism: CLI Library (inspired by Golang's Cobra)
Prism This is a library for building CLI tools written purely in Mojo! It's inspired by the Cobra package from the Golang ecosystem. https://github.com/thatstoasty/prism eg
from prism import Command


fn test(command: Arc[Command], args: List[String]) -> None:
print("Pass chromeria as a subcommand!")


fn hello(command: Arc[Command], args: List[String]) -> None:
print("Hello from Chromeria!")


fn main():
var root_command = Arc(
Command(
name="hello",
description="This is a dummy command!",
run=test,
)
)

var hello_command = Arc(Command(name="chromeria", description="This is a dummy command!", run=hello))

root_command[].add_command(hello_command)
root_command[].execute()
from prism import Command


fn test(command: Arc[Command], args: List[String]) -> None:
print("Pass chromeria as a subcommand!")


fn hello(command: Arc[Command], args: List[String]) -> None:
print("Hello from Chromeria!")


fn main():
var root_command = Arc(
Command(
name="hello",
description="This is a dummy command!",
run=test,
)
)

var hello_command = Arc(Command(name="chromeria", description="This is a dummy command!", run=hello))

root_command[].add_command(hello_command)
root_command[].execute()
mojo build my_tool.mojo -o my_tool
./my_tool # Prints Pass chromeria as a subcommand!
./my_tool chromeria # Prints Hello from Chromeria!
mojo build my_tool.mojo -o my_tool
./my_tool # Prints Pass chromeria as a subcommand!
./my_tool chromeria # Prints Hello from Chromeria!
6 replies
MModular
Created by toasty on 4/9/2024 in #questions
Iterating over Strings containing Unicode characters?
Has anyone figured out how to do this? Maxim's code works perfectly for getting the count of printable characters in a String.
alias simd_width_u8 = simdwidthof[DType.uint8]()

fn rune_count_in_string(s: String) -> Int:
var p = s._as_ptr().bitcast[DType.uint8]()
var string_byte_length = len(s)
var result = 0

@parameter
fn count[simd_width: Int](offset: Int):
result += (
((p.load[width=simd_width](offset) >> 6) != 0b10)
.cast[DType.uint8]()
.reduce_add()
.to_int()
)

vectorize[count, simd_width_u8](string_byte_length)
return result
alias simd_width_u8 = simdwidthof[DType.uint8]()

fn rune_count_in_string(s: String) -> Int:
var p = s._as_ptr().bitcast[DType.uint8]()
var string_byte_length = len(s)
var result = 0

@parameter
fn count[simd_width: Int](offset: Int):
result += (
((p.load[width=simd_width](offset) >> 6) != 0b10)
.cast[DType.uint8]()
.reduce_add()
.to_int()
)

vectorize[count, simd_width_u8](string_byte_length)
return result
And the ord and chr changes from the nightly branch help with handling conversion of a single character. But I've been unable to iterate through the codepoints of a string, as iterating through the bytes doesn't work for this use case. It's all fairly new to me, so I'm curious if anyone has already solved this problem 🙂
9 replies
MModular
Created by toasty on 3/7/2024 in #questions
Disambiguation of a call to an overloaded function when the argument satisfies multiple signatures?
I have a reader class that calls write_string() via reader.write_to() which is different depending on if the write implements a Writer or StringWriter trait.
fn write_string[W: Writer](inout writer: W, string: String) raises -> Int:
return writer.write(string.as_bytes())

fn write_string[W: StringWriter](inout writer: W, string: String) raises -> Int:
return writer.write_string(string)
fn write_string[W: Writer](inout writer: W, string: String) raises -> Int:
return writer.write(string.as_bytes())

fn write_string[W: StringWriter](inout writer: W, string: String) raises -> Int:
return writer.write_string(string)
I want to set up my reader.write_to() function to call either one depending on what the writer implements. Ideally, i'd like W to be io.Writer OR io.StringWriter but for now I overloaded the function.
fn write_to[W: io.Writer](inout self, inout writer: W) raises -> Int64:
...

fn write_to[W: io.StringWriter](inout self, inout writer: W) raises -> Int64:
...
fn write_to[W: io.Writer](inout self, inout writer: W) raises -> Int64:
...

fn write_to[W: io.StringWriter](inout self, inout writer: W) raises -> Int64:
...
When I call reader.write_to() with a writer that implements both traits, I get an error ambiguous call to 'write_to', each candidate requires 0 implicit conversions, disambiguate with an explicit cast Makes sense, but does anyone know how I can make it explicit which function I'm calling? Or how I could reorganize the code so the function call is not vague? I'm new to traits/interfaces for the most part, so any help would be appreciated!
8 replies