Разработка простого веб-приложения на Rust, часть 2b

сервер Программа перевода самородков Rust

Разработка простого веб-приложения на Rust, часть 2b

содержание

1 серия статей

В этой серии статей я задокументировал свой опыт разработки простого веб-приложения на Rust.

На данный момент у нас есть:

  1. Таргетинг и веб-сервер класса «Hello World»
  2. Разберитесь, как писать в файл

Предыдущий пост был отвратительным. На этот раз мы изучим форматы времени и даты Rust, сосредоточившись на записи времени в подходящем формате.

2 Использование Хроно

Поиск «дата» в crates.io дастпакет под названием хроно. Он горячий и часто обновляется, так что это выглядит как хороший кандидат. Из файла README у него есть отличная функция вывода даты и времени.

Во-первых, этоCargo.tomlдобавить зависимость Chrono вmain.rsСдвинуто, чтобы освободить место для экспериментов:

$ ls
Cargo.lock Cargo.toml log.txt    src        target
$ cd src/
$ ls
main.rs     web_main.rs
$ git mv main.rs main_file_writing.rs
$ touch main.rs
$ git add main.rs
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   main.rs
        copied:     main.rs -> main_file_writing.rs

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        ../log.txt

$ git commit -m 'move file writing out of the way for working with dates'
[master 4cd2b0e] move file writing out of the way for working with dates
 2 files changed, 16 deletions(-)
 rewrite src/main.rs (100%)
 copy src/{main.rs => main_file_writing.rs} (100%)

существуетCargo.tomlДобавьте зависимость Chrono к:

[package]
name = "simple-log"
version = "0.1.0"
authors = ["Joel McCracken <mccracken.joel@gmail.com>"]

[dependencies]

chrono = "0.2"

[dependencies.nickel]

git = "https://github.com/nickel-org/nickel.rs.git"

Далее в README говорится:

And put this in your crate root:

    extern crate chrono;

Я не знаю, что это значит, но я попытаюсь вставить этоmain.rstop, потому что это похоже на код Rust:

extern crate chrono;

fn main() { }

Скомпилировать:

$ cargo run
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading num v0.1.25
 Downloading rand v0.3.8
 Downloading chrono v0.2.14
   Compiling rand v0.3.8
   Compiling num v0.1.25
   Compiling chrono v0.2.14
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
     Running `/Users/joel/Projects/simple-log/target/debug/simple-log`

Ну вроде качает Chrono, и он успешно компилируется и заканчивается. Думаю, следующим шагом будет попытка использовать его. По первому примеру в README хотелось бы так:

extern crate chrono;
use chrono::*;

fn main() {
    let local: DateTime<Local> = Local::now();
    println!('{}', local);
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
main.rs:6:14: 6:16 error: unterminated character constant: '{
main.rs:6     println!('{}', local);
                       ^~
Could not compile `simple-log`.

To learn more, run the command again with --verbose.

...? После того, как я был ошеломлен на несколько секунд, я понял, что это говорит мне, что я должен использовать двойные кавычки, а не одинарные кавычки. Имеет смысл использовать одинарные кавычки для спецификации времени жизни.

После переключения с одинарных на двойные кавычки:

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
     Running `/Users/joel/Projects/simple-log/target/debug/simple-log`
2015-06-05 16:54:47.483088 -04:00

...Вау даже, это действительно просто. выглядитprintln!Какой-то интерфейс можно вызывать для печати всяких разных вещей.

Это иронично. Я легко создаю простое веб-приложение класса «Hello World» и печатаю правильно сформированное время, но трачу много времени на запись в файл. Я не знаю, что это значит. Хотя язык Rust сложен в использовании (для меня), я считаю, что сообщество Rust приложило много усилий, чтобы системные пакеты работали хорошо.

3 Записать дату и время в файл

Я думаю, следующим шагом мы должны записать эту строку в файл. Для этого я хотел бы увидеть конец предыдущей статьи:

$ cat main_file_writing.rs
use std::io::prelude::*;
use std::fs::File;
use std::io;

fn log_something(filename: &'static str, string: &'static [u8; 12]) -> io::Result<()> {
    let mut f = try!(File::create(filename));
    try!(f.write_all(string));
    Ok(())
}

fn main() {
    match log_something("log.txt", b"ITS ALIVE!!!") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

Я просто объединил приведенный выше пример с этим:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn log_something(filename: &'static str, string: &'static [u8; 12]) -> io::Result<()> {
    let mut f = try!(File::create(filename));
    try!(f.write_all(string));
    Ok(())
}

fn main() {
    let local: DateTime<Local> = Local::now();
    println!('{}', local);
    match log_something("log.txt", b"ITS ALIVE!!!") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

Скомпилировать:

$ ls
Cargo.lock      Cargo.toml      log.txt         src             target
$ pwd
/Users/joel/Projects/simple-log
$ ls
Cargo.lock      Cargo.toml      log.txt         src             target
$ rm log.txt
$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
     Running `target/debug/simple-log`
2015-06-05 17:08:57.814176 -04:00
File created!
$ cat log.txt
ITS ALIVE!!!$

Это сработало! Это действительно весело бороться с языком и очень гладко совмещать две вещи.

4 Регистратор времени сборки

Мы приближаемся к написанию настоящей, законченной, окончательной системы. Мне вдруг пришло в голову, что я мог бы написать несколько тестов для этого кода, но не волнуйтесь, я расскажу об этом позже.

Вот что должна делать эта функция:

  1. Учитывая имя файла,
  2. Создайте его, если он не существует, затем откройте файл.
  3. Создайте строку даты времени,
  4. Запишите эту строку в файл, затем закройте файл.

4,1 параu8непонимание

Моя первая попытка:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn log_time(filename: &'static str) -> io::Result<()> {

    let local: DateTime<Local> = Local::now();
    let time_str = local.format("%Y").to_string();
    let mut f = try!(File::create(filename));
    try!(f.write_all(time_str));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:13:22: 13:30 error: mismatched types:
 expected `&[u8]`,
    found `collections::string::String`
(expected &-ptr,
    found struct `collections::string::String`) [E0308]
src/main.rs:13     try!(f.write_all(time_str));
                                    ^~~~~~~~
<std macros>:1:1: 6:48 note: in expansion of try!
src/main.rs:13:5: 13:33 note: expansion site
error: aborting due to previous error
Could not compile `simple-log`.

To learn more, run the command again with --verbose.

Я знаю, что в Rust есть много строковых типов.1, похоже, мне нужен другой тип здесь. Я не знаю, как начать, поэтому я просто должен искать.

я помню, как был вРаздел документации RustСтроки специально упоминаются в . Проверьте это, там написано, что вы можете использовать&Реализация символа изStringприбыть&strпреобразование. Я чувствую, что это не то, что нам нужно, как это должно быть[u8]и&str2Тип конфликт между, попробуем:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn log_time(filename: &'static str) -> io::Result<()> {

    let local: DateTime<Local> = Local::now();
    let time_str = local.format("%Y").to_string();
    let mut f = try!(File::create(filename));
    try!(f.write_all(&time_str));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:13:22: 13:31 error: mismatched types:
 expected `&[u8]`,
    found `&collections::string::String`
(expected slice,
    found struct `collections::string::String`) [E0308]
src/main.rs:13     try!(f.write_all(&time_str));
                                    ^~~~~~~~~
<std macros>:1:1: 6:48 note: in expansion of try!
src/main.rs:13:5: 13:34 note: expansion site
error: aborting due to previous error
Could not compile `simple-log`.

To learn more, run the command again with --verbose.

Ну, очевидно, добавляя&символы могут быть толькоStringпреобразовать в&String. Кажется, это противоречит тому, что говорят документы Rust, но также может быть и то, что я не знаю, что происходит.

... и я только что прочитал конец главы о струнах. Насколько я знаю, здесь ничего нет.

Какое-то время я отсутствовал, чтобы заняться другими делами (если не считать родителей), и когда я уехал, меня осенило. До этого я всегда думалu8даUTF-8, но теперь, когда я думаю об этом, это должно означать «8-битное целое число без знака». И я помню, я виделas_bytesметод, так что давайте попробуем:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn log_time(filename: &'static str) -> io::Result<()> {
    let local: DateTime<Local> = Local::now();
    let bytes = local.format("%Y").to_string().as_bytes();
    let mut f = try!(File::create(filename));
    try!(f.write_all(bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
main.rs:10:17: 10:47 error: borrowed value does not live long enough
main.rs:10     let bytes = local.format("%Y").to_string().as_bytes();
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.rs:10:59: 14:2 note: reference must be valid for the block suffix following statement 1 at 10:
58...
main.rs:10     let bytes = local.format("%Y").to_string().as_bytes();
main.rs:11     let mut f = try!(File::create(filename));
main.rs:12     try!(f.write_all(bytes));
main.rs:13     Ok(())
main.rs:14 }
main.rs:10:5: 10:59 note: ...but borrowed value is only valid for the statement at 10:4
main.rs:10     let bytes = local.format("%Y").to_string().as_bytes();
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.rs:10:5: 10:59 help: consider using a `let` binding to increase its lifetime
main.rs:10     let bytes = local.format("%Y").to_string().as_bytes();
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `simple-log`.

To learn more, run the command again with --verbose.

Ну, янадеятьсяВещи движутся. Означает ли эта ошибка, что я что-то исправил, а есть какая-то другая ошибка, которая маскирует проблему? Я столкнулся с совершенно новой проблемой?

Странно то, что сообщение об ошибке сконцентрировано в одной строке. Я не совсем понимаю, но я думаю, что он пытается сказать мне, что мне нужно добавить оператор присваивания к методу. Давай попробуем:

fn log_time(filename: &'static str) -> io::Result<()> {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%Y").to_string();
    let bytes = formatted.as_bytes();
    let mut f = try!(File::create(filename));
    try!(f.write_all(bytes));
    Ok(())
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
     Running `target/debug/simple-log`
File created!
$ cat log.txt
2015$

чудесный! Все, что мы хотим, здесь. Прежде чем идти дальше, я хочу разглагольствовать, я немного разочарован. Без моей подсказки Rust также должен быть в состоянии сделать вывод о правильном поведении из контекста.

Тестовый сценарий:

$ ls
Cargo.lock      Cargo.toml      log.txt         src             target
$ rm log.txt
$ cargo run
     Running `target/debug/simple-log`
File created!
$ cat log.txt
2015$ cargo run
     Running `target/debug/simple-log`
File created!
$ cat log.txt
2015$

4.2 Проверка и заполнение пропусков

некоторые проблемы:

  1. Не начав еще одну строчку, это невыносимо.
  2. Формат требует некоторой обработки.
  3. Новая дата перезапишет старую.

Let's verify #3 by fixing the format. If the time changes between runs, then we will know that's what is happening.

DateTimeсерединаformatМетод использует стандартные соглашения о формате strftime. В идеале я бы хотел, чтобы время выглядело так:

Sat, Jun 6 2015 05:32:00 PM
Sun, Jun 7 2015 08:35:00 AM

……и т.д. Это должно быть достаточно читаемым для моего использования. чекДокументацияПосле этого я придумал это:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn log_time(filename: &'static str) -> io::Result<()> {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    let bytes = formatted.as_bytes();
    let mut f = try!(File::create(filename));
    try!(f.write_all(bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

контрольная работа:

$ rm log.txt
$ cargo run
     Running `target/debug/simple-log`
File created!
$ cat log.txt
Sun, Jun 07 2015 06:37:21 PM
$ sleep 5; cargo run
     Running `target/debug/simple-log`
File created!
$ cat log.txt
Sun, Jun 07 2015 06:37:41 PM

Очевидно, программа перезаписывает записи журнала, которые я хочу. Я помнюFile::createЧто здесь происходит, указано в документации к . Итак, чтобы правильно обработать файл, мне нужно снова обратиться к документации.

Я немного поискал и в основном обнаружил, что ответ не имеет значения. Затем я нашелstd::path::Pathдокументация, которая имеетexistsмодель.

На данный момент преобразования типов в моей программе становятся все более и более неуправляемыми. Я нервничаю, поэтому я собираюсь еще раз зафиксировать, прежде чем продолжить.

Я хочу изменить логику обработки строки объекта времени сlog_timeфункция, потому что создание и форматирование времени явно отличается от кода манипулирования файлом. Итак, я попробовал следующее:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn log_time_entry() -> String {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    formatted
}

fn log_time(filename: &'static str) -> io::Result<()> {
    let bytes = log_time_entry().as_bytes();
    let mut f = try!(File::create(filename));
    try!(f.write_all(bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:16:17: 16:33 error: borrowed value does not live long enough
src/main.rs:16     let bytes = log_time_entry().as_bytes();
                               ^~~~~~~~~~~~~~~~
src/main.rs:16:45: 20:2 note: reference must be valid for the block suffix following statement 0 at
 16:44...
src/main.rs:16     let bytes = log_time_entry().as_bytes();
src/main.rs:17     let mut f = try!(File::create(filename));
src/main.rs:18     try!(f.write_all(bytes));
src/main.rs:19     Ok(())
src/main.rs:20 }
src/main.rs:16:5: 16:45 note: ...but borrowed value is only valid for the statement at 16:4
src/main.rs:16     let bytes = log_time_entry().as_bytes();
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:16:5: 16:45 help: consider using a `let` binding to increase its lifetime
src/main.rs:16     let bytes = log_time_entry().as_bytes();
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `simple-log`.

To learn more, run the command again with --verbose.

Ну, это похоже на проблему, которая у меня была раньше. Требует ли заимствование или удержание, чтобы функция имела явную ссылку на ресурс? Это кажется немного странным. Я снова попытался исправить это:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn formatted_time_entry() -> String {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    formatted
}

fn log_time(filename: &'static str) -> io::Result<()> {
    let entry = formatted_time_entry();
    let bytes = entry.as_bytes();

    let mut f = try!(File::create(filename));
    try!(f.write_all(bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
     Running `target/debug/simple-log`
File created!

Итак, похоже, что добавление явной ссылки решает проблему. В любом случае, правило довольно простое.

Далее я собираюсь извлечь код манипулирования файлом в отдельную функцию:

extern crate chrono;

use std::io::prelude::*;
use std::fs::File;
use std::io;
use chrono::*;

fn formatted_time_entry() -> String {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    formatted
}

fn record_entry_in_log(filename: &str, bytes: &[u8]) -> io::Result<()> {
    let mut f = try!(File::create(filename));
    try!(f.write_all(bytes));
    Ok(())
}

fn log_time(filename: &'static str) -> io::Result<()> {
    let entry = formatted_time_entry();
    let bytes = entry.as_bytes();

    try!(record_entry_in_log(filename, &bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

Это работает нормально. Я допустил некоторые первоначальные ошибки, но они были быстро исправлены. Вот измененный код уже.

Ознакомьтесь с документациейstd::fs::File, я заметил документацию дляstd::fs::OpenOptions, именно то, что я искал. Это определенно лучше, чем использованиеstd::pathлучше.

Моя первая попытка:

extern crate chrono;

use std::io::prelude::*;
use std::fs::{File,OpenOptions};
use std::io;
use chrono::{DateTime,Local};

fn formatted_time_entry() -> String {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    formatted
}

fn record_entry_in_log(filename: &str, bytes: &[u8]) -> io::Result<()> {
    let mut file = try!(OpenOptions::new().
                        append(true).
                        create(true).
                        open(filename));
    try!(file.write_all(bytes));
    Ok(())
}

fn log_time(filename: &'static str) -> io::Result<()> {
    let entry = formatted_time_entry();
    let bytes = entry.as_bytes();

    try!(record_entry_in_log(filename, &bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(..) => println!("Error: could not create file.")
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:4:15: 4:19 warning: unused import, #[warn(unused_imports)] on by default
src/main.rs:4 use std::fs::{File,OpenOptions};
                            ^~~~
     Running `target/debug/simple-log`
Error: could not create file.

интересный. На самом деле он успешно создал файл. О, я заметил, что сообщение об ошибке состоит в том, что я жестко запрограммировалmainИнформация. Я думаю, что это будет работать следующим образом:

extern crate chrono;

use std::io::prelude::*;
use std::fs::{File,OpenOptions};
use std::io;
use chrono::{DateTime,Local};

fn formatted_time_entry() -> String {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    formatted
}

fn record_entry_in_log(filename: &str, bytes: &[u8]) -> io::Result<()> {
    let mut file = try!(OpenOptions::new().
                        append(true).
                        create(true).
                        open(filename));
    try!(file.write_all(bytes));
    Ok(())
}

fn log_time(filename: &'static str) -> io::Result<()> {
    let entry = formatted_time_entry();
    let bytes = entry.as_bytes();

    try!(record_entry_in_log(filename, &bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(e) => println!("Error: {}", e)
    }
}

=>

$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:4:15: 4:19 warning: unused import, #[warn(unused_imports)] on by default
src/main.rs:4 use std::fs::{File,OpenOptions};
                            ^~~~
     Running `target/debug/simple-log`
Error: Bad file descriptor (os error 9)

странность. Поиск сообщения об ошибке «Недопустимое описание файла», по-видимому, указывает на то, что используемое описание файла отключено. если я прокомментируюfile.write_allЗвоните, что будет?

$ rm log.txt
$ cargo run
   Compiling simple-log v0.1.0 (file:///Users/joel/Projects/simple-log)
src/main.rs:3:5: 3:25 warning: unused import, #[warn(unused_imports)] on by default
src/main.rs:3 use std::io::prelude::*;
                  ^~~~~~~~~~~~~~~~~~~~
src/main.rs:4:15: 4:19 warning: unused import, #[warn(unused_imports)] on by default
src/main.rs:4 use std::fs::{File,OpenOptions};
                            ^~~~
src/main.rs:15:40: 15:45 warning: unused variable: `bytes`, #[warn(unused_variables)] on by default
src/main.rs:15 fn record_entry_in_log(filename: &str, bytes: &[u8]) -> io::Result<()> {
                                                      ^~~~~
src/main.rs:16:9: 16:17 warning: unused variable: `file`, #[warn(unused_variables)] on by default
src/main.rs:16     let mut file = try!(OpenOptions::new().
                       ^~~~~~~~
src/main.rs:16:9: 16:17 warning: variable does not need to be mutable, #[warn(unused_mut)] on by de
fault
src/main.rs:16     let mut file = try!(OpenOptions::new().
                       ^~~~~~~~
     Running `target/debug/simple-log`
File created!
$ ls
Cargo.lock      Cargo.toml      log.txt         src             target

Как и ожидалось, есть куча неиспользуемых предупреждающих сообщений, но без этого файл создается.

Это кажется немного глупым, но я попытался добавить в цепочку вызовов функций.write(true)После этого заработало. семантически.append(true)это значит.write(true), но я думаю, что это не так в правилах.

Сделал это и все заработало! Окончательный версия:

extern crate chrono;

use std::io::prelude::*;
use std::fs::{File,OpenOptions};
use std::io;
use chrono::{DateTime,Local};

fn formatted_time_entry() -> String {
    let local: DateTime<Local> = Local::now();
    let formatted = local.format("%a, %b %d %Y %I:%M:%S %p\n").to_string();
    formatted
}

fn record_entry_in_log(filename: &str, bytes: &[u8]) -> io::Result<()> {
    let mut file = try!(OpenOptions::new().
                        append(true).
                        write(true).
                        create(true).
                        open(filename));
    try!(file.write_all(bytes));
    Ok(())
}

fn log_time(filename: &'static str) -> io::Result<()> {
    let entry = formatted_time_entry();
    let bytes = entry.as_bytes();

    try!(record_entry_in_log(filename, &bytes));
    Ok(())
}

fn main() {
    match log_time("log.txt") {
        Ok(..) => println!("File created!"),
        Err(e) => println!("Error: {}", e)
    }
}

=>

$ ls
Cargo.lock      Cargo.toml      src             target
$ cargo run
     Running `target/debug/simple-log`
File created!
$ cargo run
     Running `target/debug/simple-log`
File created!
$ cat log.txt
Sun, Jun 07 2015 10:40:01 PM
Sun, Jun 07 2015 10:40:05 PM

5 Заключение и следующие шаги

Ржавчина становится легче для меня. Теперь у меня есть работающий однофункциональный код, с которым можно работать, и я вполне уверен в разработке следующей части программы.

Когда я впервые планировал эту серию, моей следующей задачей было интегрировать код регистрации иnickel.rsкод, но пока, я думаю, это довольно просто. Я предполагаю, что следующей сложной частью будет выборпарсинг элемента.

Серия статей: Разработка простого веб-приложения на Rust

сноска:

1Очень разумно иметь много видов строк. Строки — это сложные объекты, которые трудно понять правильно. К сожалению, на первый взгляд строки настолько просты, что подобные вещи кажутся излишне сложными.

2Я тоже не знаю, о чем говорю. Все это теперь в пределах досягаемости.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.