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

Improve CLI output #436

Merged
merged 19 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documentation/docs/detailed-techniques.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ message SomeData { ... }
This applies same to marked Protobuf messages.

```proto title="Protobuf"
// [RINF:DART-SIGNAL]
// [DART-SIGNAL]
// This is an audio data sample of...
// contains...
// responsible for...
Expand Down
4 changes: 2 additions & 2 deletions documentation/docs/frequently-asked-questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,13 @@ However, if you really need to store some state in a Flutter widget, you can ach
syntax = "proto3";
package tutorial_resource;

// [RINF:DART-SIGNAL]
// [DART-SIGNAL]
message MyUniqueInput {
int32 interaction_id = 1;
int32 before_number = 2;
}

// [RINF:RUST-SIGNAL]
// [RUST-SIGNAL]
message MyUniqueOutput {
int32 interaction_id = 1;
int32 after_number = 2;
Expand Down
20 changes: 10 additions & 10 deletions documentation/docs/messaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ There are special comments that you can mark messages with.

## 📢 Channels

`[RINF:RUST-SIGNAL]` generates a message channel from Rust to Dart.
`[RUST-SIGNAL]` generates a message channel from Rust to Dart.

```proto title="Protobuf"
// [RINF:RUST-SIGNAL]
// [RUST-SIGNAL]
message MyDataOutput { ... }
```

Expand All @@ -29,10 +29,10 @@ StreamBuilder(
)
```

Use `[RINF:RUST-SIGNAL-BINARY]` to include binary data without the overhead of serialization.
Use `[RUST-SIGNAL-BINARY]` to include binary data without the overhead of serialization.

```proto title="Protobuf"
// [RINF:RUST-SIGNAL-BINARY]
// [RUST-SIGNAL-BINARY]
message MyDataOutput { ... }
```

Expand All @@ -56,10 +56,10 @@ StreamBuilder(
)
```

`[RINF:DART-SIGNAL]` generates a message channel from Dart to Rust.
`[DART-SIGNAL]` generates a message channel from Dart to Rust.

```proto title="Protobuf"
// [RINF:DART-SIGNAL]
// [DART-SIGNAL]
message MyDataInput { ... }
```

Expand All @@ -75,10 +75,10 @@ while let Some(dart_signal) = receiver.recv().await {
}
```

Use `[RINF:DART-SIGNAL-BINARY]` to include binary data without the overhead of serialization.
Use `[DART-SIGNAL-BINARY]` to include binary data without the overhead of serialization.

```proto title="Protobuf"
// [RINF:DART-SIGNAL-BINARY]
// [DART-SIGNAL-BINARY]
message MyDataInput { ... }
```

Expand All @@ -98,9 +98,9 @@ while let Some(dart_signal) = receiver.recv().await {

## 🔖 Attributes

`[RINF:RUST-ATTRIBUTE(...)]` writes an attribute above the generated message struct in Rust. This is useful when you want to automatically implement a trait for the message struct in Rust.
`[RUST-ATTRIBUTE(...)]` writes an attribute above the generated message struct in Rust. This is useful when you want to automatically implement a trait for the message struct in Rust.

```proto title="Protobuf"
// [RINF:RUST-ATTRIBUTE(#[derive(Hash)])]
// [RUST-ATTRIBUTE(#[derive(Hash)])]
message MyDataInput { ... }
```
12 changes: 6 additions & 6 deletions documentation/docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ child: Column(

Let's say that you want to create a new button in Dart that sends an array of numbers and a string to Rust. We need a signal to notify Rust that a user event has occurred.

Write a new `.proto` file in the `./messages` directory with a new message. Note that the message should have the comment `[RINF:DART-SIGNAL]` above it.
Write a new `.proto` file in the `./messages` directory with a new message. Note that the message should have the comment `[DART-SIGNAL]` above it.

```proto title="messages/tutorial_messages.proto"
syntax = "proto3";
package tutorial_messages;

// [RINF:DART-SIGNAL]
// [DART-SIGNAL]
message MyPreciousData {
repeated int32 input_numbers = 1;
string input_string = 2;
Expand Down Expand Up @@ -99,13 +99,13 @@ flutter: ZERO-COST ABSTRACTION

Let's say that you want to send increasing numbers every second from Rust to Dart.

Define the message. Note that the message should have the comment `[RINF:RUST-SIGNAL]` above it.
Define the message. Note that the message should have the comment `[RUST-SIGNAL]` above it.

```proto title="messages/tutorial_messages.proto"
syntax = "proto3";
package tutorial_messages;

// [RINF:RUST-SIGNAL]
// [RUST-SIGNAL]
message MyAmazingNumber { int32 current_number = 1; }
```

Expand Down Expand Up @@ -172,10 +172,10 @@ You can easily show the updated state on the screen by combining those two ways
syntax = "proto3";
package tutorial_messages;

// [RINF:DART-SIGNAL]
// [DART-SIGNAL]
message MyTreasureInput {}

// [RINF:RUST-SIGNAL]
// [RUST-SIGNAL]
message MyTreasureOutput { int32 current_value = 1; }
```

Expand Down
144 changes: 100 additions & 44 deletions flutter_package/bin/rinf.dart
Original file line number Diff line number Diff line change
@@ -1,55 +1,111 @@
import 'package:args/command_runner.dart';
import 'package:chalkdart/chalkstrings.dart';

import 'src/config.dart';
import 'src/helpers.dart';
import 'src/message.dart';
import 'src/internet.dart';
import 'src/common.dart';

Future<void> main(List<String> args) async {
if (args.isEmpty) {
print('No operation is provided.');
print('Use `rinf --help` to see all available operations.');
return;
}
// After running `dart run rinf`,
// Unnecessary two lines of
//`Building package executable...\nBuilt rinf:rinf.` appear.
// Remove those before proceeding.
removeCliLines(2);

final rinfConfig = await loadVerifiedRinfConfig('pubspec.yaml');
// Check the internet connection status and rembember it.
await checkConnectivity();

switch (args[0]) {
case 'config':
print(rinfConfig);
break;
case 'template':
await applyRustTemplate(messageConfig: rinfConfig.message);
break;
case 'message':
if (args.contains('--watch') || args.contains('-w')) {
await watchAndGenerateMessageCode(messageConfig: rinfConfig.message);
} else {
await generateMessageCode(messageConfig: rinfConfig.message);
}
break;
case 'wasm':
if (args.contains('--release') || args.contains('-r')) {
await buildWebassembly(isReleaseMode: true);
} else {
await buildWebassembly();
}
break;
case '--help':
case '-h':
print('Usage: rinf [arguments]');
print('Arguments:');
print(' -h, --help Shows this usage information.');
print(' config Shows current Rinf configuration'
'\n resolved from `pubspec.yaml`'
'\n with defaults applied.');
print(' template Applies Rust template'
'\n to current Flutter project.');
print(' message Generates message code from `.proto` files.');
print(' -w, --watch Continuously watches `.proto` files.');
print(' wasm Builds webassembly module.');
print(' -r, --release Builds in release mode.');
default:
print('No such operation is available.');
print('Use `rinf --help` to see all available operations.');
// Parse CLI arguments and run the corresponding function.
final runner = CommandRunner(
'rinf',
'Helper commands for building apps with Rust in Flutter.',
usageLineLength: 80,
)
..addCommand(ConfigCommand())
..addCommand(TemplateCommand())
..addCommand(MessageCommand())
..addCommand(WasmCommand());

try {
await runner.run(args);
} catch (error) {
// Print the error gracefully without backtrace.
print(error.toString().trim().red);
}
}

class ConfigCommand extends Command {
final name = 'config';
final description = 'Shows current Rinf configuration' +
' resolved from `pubspec.yaml` with defaults applied.';

ConfigCommand() {}

Future<void> run() async {
final rinfConfig = await loadVerifiedRinfConfig('pubspec.yaml');
print(rinfConfig.toString().dim);
}
}

class TemplateCommand extends Command {
final name = 'template';
final description = 'Applies Rust template to the current Flutter project.';

TemplateCommand() {}

Future<void> run() async {
final rinfConfig = await loadVerifiedRinfConfig('pubspec.yaml');
await applyRustTemplate(messageConfig: rinfConfig.message);
}
}

class MessageCommand extends Command {
final name = 'message';
final description = 'Generates message code from `.proto` files.';

MessageCommand() {
argParser.addFlag(
'watch',
abbr: 'w',
help: 'Continuously watches `.proto` files.',
);
}

Future<void> run() async {
final results = argResults;
if (results == null) {
return;
}
final watch = results.flag('watch');
final rinfConfig = await loadVerifiedRinfConfig('pubspec.yaml');
if (watch) {
await watchAndGenerateMessageCode(messageConfig: rinfConfig.message);
} else {
await generateMessageCode(messageConfig: rinfConfig.message);
}
}
}

class WasmCommand extends Command {
final name = 'wasm';
final description = 'Builds the webassembly module for the web.';

WasmCommand() {
argParser.addFlag(
'release',
abbr: 'r',
help: 'Builds in release mode.',
);
}

Future<void> run() async {
final results = argResults;
if (results == null) {
return;
}
final release = results.flag('release');
await buildWebassembly(release);
}
}
11 changes: 11 additions & 0 deletions flutter_package/bin/src/common.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

extension UriJoin on Uri {
Uri join(String path) {
if (path.isEmpty || path == '/') {
Expand All @@ -12,3 +14,12 @@ extension UriJoin on Uri {
}
}
}

/// Removes an existing line from the CLI.
void removeCliLines(int lines) {
for (var i = 0; i < lines; i++) {
stdout.write('\x1B[1A'); // Move the cursor up one line
stdout.write('\x1B[2K'); // Clear the line
stdout.write('\r'); // Return the cursor to the front
}
}
1 change: 1 addition & 0 deletions flutter_package/bin/src/config.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:io';

import 'package:yaml/yaml.dart';

class RinfConfigMessage {
Expand Down
Loading
Loading