mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-02 03:19:41 +03:00
add lib.leo support
This commit is contained in:
parent
8825a0741c
commit
9c2a0e4ec6
@ -2,8 +2,8 @@ use crate::{
|
|||||||
cli::*,
|
cli::*,
|
||||||
cli_types::*,
|
cli_types::*,
|
||||||
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
|
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
|
||||||
errors::{BuildError, CLIError},
|
errors::CLIError,
|
||||||
files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME},
|
files::{ChecksumFile, LibFile, MainFile, Manifest, LIB_FILE_NAME, MAIN_FILE_NAME},
|
||||||
};
|
};
|
||||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ pub struct BuildCommand;
|
|||||||
|
|
||||||
impl CLI for BuildCommand {
|
impl CLI for BuildCommand {
|
||||||
type Options = ();
|
type Options = ();
|
||||||
type Output = (Compiler<Fq, EdwardsGroupType>, bool);
|
type Output = Option<(Compiler<Fq, EdwardsGroupType>, bool)>;
|
||||||
|
|
||||||
const ABOUT: AboutType = "Compile the current package as a program";
|
const ABOUT: AboutType = "Compile the current package as a program";
|
||||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||||
@ -46,58 +46,72 @@ impl CLI for BuildCommand {
|
|||||||
package_path.pop();
|
package_path.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the main file exists
|
// Compile the package starting with the lib.leo file
|
||||||
if !MainFile::exists_at(&package_path) {
|
if LibFile::exists_at(&package_path) {
|
||||||
return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
|
// Construct the path to the library file in the source directory
|
||||||
}
|
let mut lib_file_path = package_path.clone();
|
||||||
|
lib_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
|
lib_file_path.push(LIB_FILE_NAME);
|
||||||
|
|
||||||
// Create the outputs directory
|
// Compile the library file but do not output
|
||||||
OutputsDirectory::create(&package_path)?;
|
let _program = Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), lib_file_path)?;
|
||||||
|
|
||||||
// Construct the path to the main file in the source directory
|
|
||||||
let mut main_file_path = package_path.clone();
|
|
||||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
|
||||||
main_file_path.push(MAIN_FILE_NAME);
|
|
||||||
|
|
||||||
// Load the program at `main_file_path`
|
|
||||||
let program = Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
|
||||||
|
|
||||||
// Compute the current program checksum
|
|
||||||
let program_checksum = program.checksum()?;
|
|
||||||
|
|
||||||
// Generate the program on the constraint system and verify correctness
|
|
||||||
{
|
|
||||||
let mut cs = KeypairAssembly::<Bls12_377> {
|
|
||||||
num_inputs: 0,
|
|
||||||
num_aux: 0,
|
|
||||||
num_constraints: 0,
|
|
||||||
at: vec![],
|
|
||||||
bt: vec![],
|
|
||||||
ct: vec![],
|
|
||||||
};
|
|
||||||
let temporary_program = program.clone();
|
|
||||||
let output = temporary_program.compile_constraints(&mut cs)?;
|
|
||||||
log::debug!("Compiled constraints - {:#?}", output);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a checksum file exists, check if it differs from the new checksum
|
|
||||||
let checksum_file = ChecksumFile::new(&package_name);
|
|
||||||
let checksum_differs = if checksum_file.exists_at(&package_path) {
|
|
||||||
let previous_checksum = checksum_file.read_from(&package_path)?;
|
|
||||||
program_checksum != previous_checksum
|
|
||||||
} else {
|
|
||||||
// By default, the checksum differs if there is no checksum to compare against
|
|
||||||
true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// If checksum differs, compile the program
|
// Compile the main.leo file along with constraints
|
||||||
if checksum_differs {
|
if MainFile::exists_at(&package_path) {
|
||||||
// Write the new checksum to the outputs directory
|
// Create the outputs directory
|
||||||
checksum_file.write_to(&path, program_checksum)?;
|
OutputsDirectory::create(&package_path)?;
|
||||||
|
|
||||||
|
// Construct the path to the main file in the source directory
|
||||||
|
let mut main_file_path = package_path.clone();
|
||||||
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
|
main_file_path.push(MAIN_FILE_NAME);
|
||||||
|
|
||||||
|
// Load the program at `main_file_path`
|
||||||
|
let program =
|
||||||
|
Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
||||||
|
|
||||||
|
// Compute the current program checksum
|
||||||
|
let program_checksum = program.checksum()?;
|
||||||
|
|
||||||
|
// Generate the program on the constraint system and verify correctness
|
||||||
|
{
|
||||||
|
let mut cs = KeypairAssembly::<Bls12_377> {
|
||||||
|
num_inputs: 0,
|
||||||
|
num_aux: 0,
|
||||||
|
num_constraints: 0,
|
||||||
|
at: vec![],
|
||||||
|
bt: vec![],
|
||||||
|
ct: vec![],
|
||||||
|
};
|
||||||
|
let temporary_program = program.clone();
|
||||||
|
let output = temporary_program.compile_constraints(&mut cs)?;
|
||||||
|
log::debug!("Compiled constraints - {:#?}", output);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a checksum file exists, check if it differs from the new checksum
|
||||||
|
let checksum_file = ChecksumFile::new(&package_name);
|
||||||
|
let checksum_differs = if checksum_file.exists_at(&package_path) {
|
||||||
|
let previous_checksum = checksum_file.read_from(&package_path)?;
|
||||||
|
program_checksum != previous_checksum
|
||||||
|
} else {
|
||||||
|
// By default, the checksum differs if there is no checksum to compare against
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
// If checksum differs, compile the program
|
||||||
|
if checksum_differs {
|
||||||
|
// Write the new checksum to the outputs directory
|
||||||
|
checksum_file.write_to(&path, program_checksum)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!("Compiled program in {:?}", main_file_path);
|
||||||
|
|
||||||
|
return Ok(Some((program, checksum_differs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Compiled program in {:?}", main_file_path);
|
// Return None when compiling a package for publishing
|
||||||
|
// The published package does not need to have a main.leo
|
||||||
Ok((program, checksum_differs))
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
use crate::{
|
||||||
|
cli::*,
|
||||||
|
cli_types::*,
|
||||||
|
commands::BuildCommand,
|
||||||
|
directories::SOURCE_DIRECTORY_NAME,
|
||||||
|
errors::{CLIError, RunError},
|
||||||
|
files::{Manifest, MAIN_FILE_NAME},
|
||||||
|
};
|
||||||
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use std::{convert::TryFrom, env::current_dir};
|
use std::{convert::TryFrom, env::current_dir};
|
||||||
@ -24,14 +31,26 @@ impl CLI for DeployCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
|
||||||
|
|
||||||
// Get the package name
|
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
|
||||||
|
|
||||||
log::info!("Unimplemented - `leo deploy`");
|
match BuildCommand::output(options)? {
|
||||||
|
Some((_program, _checksum_differs)) => {
|
||||||
|
// Get the package name
|
||||||
|
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
Ok(())
|
log::info!("Unimplemented - `leo deploy`");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut main_file_path = path.clone();
|
||||||
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
|
main_file_path.push(MAIN_FILE_NAME);
|
||||||
|
|
||||||
|
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||||
|
main_file_path.into_os_string(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
use crate::{
|
||||||
|
cli::*,
|
||||||
|
cli_types::*,
|
||||||
|
commands::BuildCommand,
|
||||||
|
directories::SOURCE_DIRECTORY_NAME,
|
||||||
|
errors::{CLIError, RunError},
|
||||||
|
files::{Manifest, MAIN_FILE_NAME},
|
||||||
|
};
|
||||||
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use std::{convert::TryFrom, env::current_dir};
|
use std::{convert::TryFrom, env::current_dir};
|
||||||
@ -24,14 +31,26 @@ impl CLI for LoadCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
|
||||||
|
|
||||||
// Get the package name
|
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
|
||||||
|
|
||||||
log::info!("Unimplemented - `leo deploy`");
|
match BuildCommand::output(options)? {
|
||||||
|
Some((_program, _checksum_differs)) => {
|
||||||
|
// Get the package name
|
||||||
|
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
Ok(())
|
log::info!("Unimplemented - `leo load`");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut main_file_path = path.clone();
|
||||||
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
|
main_file_path.push(MAIN_FILE_NAME);
|
||||||
|
|
||||||
|
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||||
|
main_file_path.into_os_string(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,9 @@ impl CLI for PublishCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
// Build all program files.
|
||||||
|
// It's okay if there's just a lib.leo file here
|
||||||
|
let _output = BuildCommand::output(options)?;
|
||||||
|
|
||||||
// Get the package name
|
// Get the package name
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
|
@ -2,8 +2,9 @@ use crate::{
|
|||||||
cli::*,
|
cli::*,
|
||||||
cli_types::*,
|
cli_types::*,
|
||||||
commands::BuildCommand,
|
commands::BuildCommand,
|
||||||
errors::{CLIError, VerificationKeyFileError},
|
directories::SOURCE_DIRECTORY_NAME,
|
||||||
files::{Manifest, ProvingKeyFile, VerificationKeyFile},
|
errors::{CLIError, RunError, VerificationKeyFileError},
|
||||||
|
files::{Manifest, ProvingKeyFile, VerificationKeyFile, MAIN_FILE_NAME},
|
||||||
};
|
};
|
||||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||||
|
|
||||||
@ -40,66 +41,77 @@ impl CLI for SetupCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||||
let (program, checksum_differs) = BuildCommand::output(options)?;
|
|
||||||
|
|
||||||
// Get the package name
|
// Get the package name
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
let package_name = Manifest::try_from(&path)?.get_package_name();
|
let package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
// Check if a proving key and verification key already exists
|
match BuildCommand::output(options)? {
|
||||||
let keys_exist = ProvingKeyFile::new(&package_name).exists_at(&path)
|
Some((program, checksum_differs)) => {
|
||||||
&& VerificationKeyFile::new(&package_name).exists_at(&path);
|
// Check if a proving key and verification key already exists
|
||||||
|
let keys_exist = ProvingKeyFile::new(&package_name).exists_at(&path)
|
||||||
|
&& VerificationKeyFile::new(&package_name).exists_at(&path);
|
||||||
|
|
||||||
// If keys do not exist or the checksum differs, run the program setup
|
// If keys do not exist or the checksum differs, run the program setup
|
||||||
if !keys_exist || checksum_differs {
|
if !keys_exist || checksum_differs {
|
||||||
// Start the timer
|
// Start the timer
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
// Run the program setup operation
|
// Run the program setup operation
|
||||||
let rng = &mut thread_rng();
|
let rng = &mut thread_rng();
|
||||||
let parameters = generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap();
|
let parameters = generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap();
|
||||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
||||||
|
|
||||||
// End the timer
|
// End the timer
|
||||||
log::info!("Setup completed in {:?} milliseconds", start.elapsed().as_millis());
|
log::info!("Setup completed in {:?} milliseconds", start.elapsed().as_millis());
|
||||||
|
|
||||||
// TODO (howardwu): Convert parameters to a 'proving key' struct for serialization.
|
// TODO (howardwu): Convert parameters to a 'proving key' struct for serialization.
|
||||||
// Write the proving key file to the outputs directory
|
// Write the proving key file to the outputs directory
|
||||||
let mut proving_key = vec![];
|
let mut proving_key = vec![];
|
||||||
parameters.write(&mut proving_key)?;
|
parameters.write(&mut proving_key)?;
|
||||||
ProvingKeyFile::new(&package_name).write_to(&path, &proving_key)?;
|
ProvingKeyFile::new(&package_name).write_to(&path, &proving_key)?;
|
||||||
|
|
||||||
// Write the proving key file to the outputs directory
|
// Write the proving key file to the outputs directory
|
||||||
let mut verification_key = vec![];
|
let mut verification_key = vec![];
|
||||||
prepared_verifying_key.write(&mut verification_key)?;
|
prepared_verifying_key.write(&mut verification_key)?;
|
||||||
VerificationKeyFile::new(&package_name).write_to(&path, &verification_key)?;
|
VerificationKeyFile::new(&package_name).write_to(&path, &verification_key)?;
|
||||||
}
|
|
||||||
|
|
||||||
// Read the proving key file from the outputs directory
|
|
||||||
let proving_key = ProvingKeyFile::new(&package_name).read_from(&path)?;
|
|
||||||
let parameters = Parameters::<Bls12_377>::read(proving_key.as_slice(), true)?;
|
|
||||||
|
|
||||||
// Read the proving key file from the outputs directory
|
|
||||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
|
||||||
{
|
|
||||||
// Load the stored verification key from the outputs directory
|
|
||||||
let stored_vk = VerificationKeyFile::new(&package_name).read_from(&path)?;
|
|
||||||
|
|
||||||
// Convert the prepared_verifying_key to a buffer
|
|
||||||
let mut verification_key = vec![];
|
|
||||||
prepared_verifying_key.write(&mut verification_key)?;
|
|
||||||
|
|
||||||
// Check that the constructed prepared verification key matches the stored verification key
|
|
||||||
let compare: Vec<(u8, u8)> = verification_key.into_iter().zip(stored_vk.into_iter()).collect();
|
|
||||||
for (a, b) in compare {
|
|
||||||
if a != b {
|
|
||||||
return Err(VerificationKeyFileError::IncorrectVerificationKey.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the proving key file from the outputs directory
|
||||||
|
let proving_key = ProvingKeyFile::new(&package_name).read_from(&path)?;
|
||||||
|
let parameters = Parameters::<Bls12_377>::read(proving_key.as_slice(), true)?;
|
||||||
|
|
||||||
|
// Read the proving key file from the outputs directory
|
||||||
|
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
||||||
|
{
|
||||||
|
// Load the stored verification key from the outputs directory
|
||||||
|
let stored_vk = VerificationKeyFile::new(&package_name).read_from(&path)?;
|
||||||
|
|
||||||
|
// Convert the prepared_verifying_key to a buffer
|
||||||
|
let mut verification_key = vec![];
|
||||||
|
prepared_verifying_key.write(&mut verification_key)?;
|
||||||
|
|
||||||
|
// Check that the constructed prepared verification key matches the stored verification key
|
||||||
|
let compare: Vec<(u8, u8)> = verification_key.into_iter().zip(stored_vk.into_iter()).collect();
|
||||||
|
for (a, b) in compare {
|
||||||
|
if a != b {
|
||||||
|
return Err(VerificationKeyFileError::IncorrectVerificationKey.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!("Completed program setup");
|
||||||
|
|
||||||
|
Ok((program, parameters, prepared_verifying_key))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut main_file_path = path.clone();
|
||||||
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
|
main_file_path.push(MAIN_FILE_NAME);
|
||||||
|
|
||||||
|
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||||
|
main_file_path.into_os_string(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Completed program setup");
|
|
||||||
|
|
||||||
Ok((program, parameters, prepared_verifying_key))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
use crate::{
|
||||||
|
cli::*,
|
||||||
|
cli_types::*,
|
||||||
|
commands::BuildCommand,
|
||||||
|
directories::SOURCE_DIRECTORY_NAME,
|
||||||
|
errors::{CLIError, RunError},
|
||||||
|
files::{Manifest, MAIN_FILE_NAME},
|
||||||
|
};
|
||||||
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use std::{convert::TryFrom, env::current_dir};
|
use std::{convert::TryFrom, env::current_dir};
|
||||||
@ -24,14 +31,26 @@ impl CLI for UnloadCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
|
||||||
|
|
||||||
// Get the package name
|
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
|
||||||
|
|
||||||
log::info!("Unimplemented - `leo deploy`");
|
match BuildCommand::output(options)? {
|
||||||
|
Some((_program, _checksum_differs)) => {
|
||||||
|
// Get the package name
|
||||||
|
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
Ok(())
|
log::info!("Unimplemented - `leo load`");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut main_file_path = path.clone();
|
||||||
|
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||||
|
main_file_path.push(MAIN_FILE_NAME);
|
||||||
|
|
||||||
|
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||||
|
main_file_path.into_os_string(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
leo/errors/files/lib.rs
Normal file
19
leo/errors/files/lib.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use std::io;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum LibFileError {
|
||||||
|
#[error("{}: {}", _0, _1)]
|
||||||
|
Crate(&'static str, String),
|
||||||
|
|
||||||
|
#[error("creating: {}", _0)]
|
||||||
|
Creating(io::Error),
|
||||||
|
|
||||||
|
#[error("writing: {}", _0)]
|
||||||
|
Writing(io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for LibFileError {
|
||||||
|
fn from(error: std::io::Error) -> Self {
|
||||||
|
LibFileError::Crate("std::io", format!("{}", error))
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,9 @@ pub use self::gitignore::*;
|
|||||||
pub mod inputs;
|
pub mod inputs;
|
||||||
pub use self::inputs::*;
|
pub use self::inputs::*;
|
||||||
|
|
||||||
|
pub mod lib;
|
||||||
|
pub use self::lib::*;
|
||||||
|
|
||||||
pub mod main;
|
pub mod main;
|
||||||
pub use self::main::*;
|
pub use self::main::*;
|
||||||
|
|
||||||
|
56
leo/files/lib.rs
Normal file
56
leo/files/lib.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//! The `lib.leo` file.
|
||||||
|
|
||||||
|
use crate::{directories::source::SOURCE_DIRECTORY_NAME, errors::LibFileError};
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::{fs::File, io::Write, path::PathBuf};
|
||||||
|
|
||||||
|
pub static LIB_FILE_NAME: &str = "lib.leo";
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct LibFile {
|
||||||
|
pub package_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LibFile {
|
||||||
|
pub fn new(package_name: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
package_name: package_name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exists_at(path: &PathBuf) -> bool {
|
||||||
|
let mut path = path.to_owned();
|
||||||
|
if path.is_dir() {
|
||||||
|
if !path.ends_with(SOURCE_DIRECTORY_NAME) {
|
||||||
|
path.push(PathBuf::from(SOURCE_DIRECTORY_NAME));
|
||||||
|
}
|
||||||
|
path.push(PathBuf::from(LIB_FILE_NAME));
|
||||||
|
}
|
||||||
|
path.exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_to(self, path: &PathBuf) -> Result<(), LibFileError> {
|
||||||
|
let mut path = path.to_owned();
|
||||||
|
if path.is_dir() {
|
||||||
|
if !path.ends_with(SOURCE_DIRECTORY_NAME) {
|
||||||
|
path.push(PathBuf::from(SOURCE_DIRECTORY_NAME));
|
||||||
|
}
|
||||||
|
path.push(PathBuf::from(LIB_FILE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = File::create(&path)?;
|
||||||
|
Ok(file.write_all(self.template().as_bytes())?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn template(&self) -> String {
|
||||||
|
format!(
|
||||||
|
r#"// The '{}' lib function.
|
||||||
|
circuit Circ {{
|
||||||
|
c: field
|
||||||
|
}}
|
||||||
|
"#,
|
||||||
|
self.package_name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,9 @@ pub use self::inputs::*;
|
|||||||
pub mod gitignore;
|
pub mod gitignore;
|
||||||
pub use self::gitignore::*;
|
pub use self::gitignore::*;
|
||||||
|
|
||||||
|
pub mod lib;
|
||||||
|
pub use self::lib::*;
|
||||||
|
|
||||||
pub mod main;
|
pub mod main;
|
||||||
pub use self::main::*;
|
pub use self::main::*;
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ impl<'ast> From<AstImportSymbol<'ast>> for ImportSymbol {
|
|||||||
impl fmt::Display for ImportSymbol {
|
impl fmt::Display for ImportSymbol {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if self.alias.is_some() {
|
if self.alias.is_some() {
|
||||||
write!(f, "\t{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
write!(f, "{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
||||||
} else {
|
} else {
|
||||||
write!(f, "\t{}", self.symbol)
|
write!(f, "{}", self.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user